我正在尝试将命令绑定到WPF中的menuitem.我正在使用与我所有其他命令绑定一样的方法,但我无法弄清楚为什么它在这里不起作用.
我正在绑定我的命令,如下所示:
Command = "{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.MyCommand}"
Run Code Online (Sandbox Code Playgroud)
这是它出错的地方(这是在UserControl中)
<Button Height="40" Margin="0,2,0,0" CommandParameter="{Binding Name}"
Command = "{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.ConnectCommand}">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="Remove" CommandParameter="{Binding Name}"
Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.RemoveCommand}"/>
</ContextMenu>
</Button.ContextMenu>
...
Run Code Online (Sandbox Code Playgroud)
第一个命令绑定就像它应该的那样工作,但第二个命令绑定拒绝做任何事情.我已经尝试更改祖先级别并命名我的控件通过ElementName而不是RelativeSource访问它,但仍然没有变化.它一直说"找不到参考资料的来源......"
我错过了什么?
Met*_*ter 27
(编辑)既然你提到这是在ItemsControl的模板中,事情是不同的:
1)从这个博客获取BindingProxy类(并阅读博客,因为这是有趣的信息):如何在未继承DataContext时绑定到数据.
基本上ItemsControl(或ContextMenu)中的元素不是可视树或逻辑树的一部分,因此无法找到UserControl的DataContext.我很抱歉没有在这里写更多内容,但作者已经做得很好,一步一步地解释它,所以我无法用几句话给出完整的解释.
2)做这样的事情:(你可能需要调整一下以使其在你的控制中工作):
一个.这将使您可以使用StaticResource访问UserControl DataContext:
<UserControl.Resources>
<BindingProxy
x:Key="DataContextProxy"
Data="{Binding}" />
</UserControl.Resources>
Run Code Online (Sandbox Code Playgroud)
湾 这使用(a)中定义的DataContextProxy:
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="Remove" CommandParameter="{Binding Name}"
Command="{Binding Path=Data.RemoveCommand, Source={StaticResource DataContextProxy}}"/>
</ContextMenu>
Run Code Online (Sandbox Code Playgroud)
这在树和数据网格等方面对我们有用.
kos*_*dim 11
ContextMenu位于不同的逻辑树中,这就是RelativeSource无法工作的原因.但是上下文菜单从其"容器"继承DataContext,在这种情况下它是Button.在通常情况下就足够了,但在您的情况下,您需要两个"数据上下文",ItemsControl项和ItemsControl本身.我认为您别无选择,只能将您的视图模型合并为一个,实现自定义类以用作ItemsControl项数据上下文并包含"Name"和"Remove command",或者您的项目视图模型可以定义RemoveCommand"proxy",即会在内部调用父命令
编辑:我略微改变了狒狒的代码,它必须以这种方式工作:
<Button Height="40" Margin="0,2,0,0" CommandParameter="{Binding Name}"
Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}"
Command = "{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.ConnectCommand}">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="Remove"
CommandParameter="{Binding Name}"
Command="{Binding Path=PlacementTarget.Tag.DataContext.RemoveCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"/>
</ContextMenu>
</Button.ContextMenu>
Run Code Online (Sandbox Code Playgroud)
小智 5
koshdim处处可见,它就像一个魅力!!谢谢科什丁
我修改了他的代码以适合我的上下文菜单
<DataGrid
AutoGenerateColumns="False"
HeadersVisibility="Column"
Name="dgLosses"
SelectedItem="{Binding SelectedItem, Mode= TwoWay}"
AllowDrop="True"
ItemsSource="{Binding Losses}"
Tag="{Binding DataContext,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}">
<DataGrid.ContextMenu >
<ContextMenu >
<MenuItem Header="Move to Top " Command="{Binding PlacementTarget.Tag.MoveToTopCommand,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ContextMenu}}" ></MenuItem>
<MenuItem Header="Move to Period 1" Command="{Binding PlacementTarget.Tag.MoveToPeriod1Command,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ContextMenu}}" ></MenuItem>
<MenuItem Header="Move to Period 2" Command="{Binding PlacementTarget.Tag.MoveToPeriod2Command,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ContextMenu}}" ></MenuItem>
<MenuItem Header="Move to Period 3" Command="{Binding PlacementTarget.Tag.MoveToPeriod3Command,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ContextMenu}}" ></MenuItem>
</ContextMenu>
</DataGrid.ContextMenu>
Run Code Online (Sandbox Code Playgroud)