2012-07-12 46 views
2

是否有可能为WPF CommandCommandParameter有不同的Datacontext命令和命令参数的不同Datacontext

<UserControl> 
<UserControl.Resources> 
    <viewmodels:ListViewGridBaseViewModel x:Key="vm" /> 
</UserControl.Resources> 
<Grid> 
    <ContentControl x:Name="currentContent" 
        Content="{Binding Path=ListGrid}" > 
     <ContentControl.ContextMenu> 
      <ContextMenu > 
       <MenuItem Command="{Binding Path=Save}" 
          CommandParameter="{Binding ElementName=currentContent}" 
          DataContext="{StaticResource ResourceKey=vm}" 
          Header="Save"> 
        <MenuItem.Icon> 
         <Image Source="{StaticResource ResourceKey=Save}" 
           Height="16" 
           Width="16"/> 
        </MenuItem.Icon> 
       </MenuItem> 
       <MenuItem Command="{Binding Path=Revert}" 
          DataContext="{StaticResource ResourceKey=vm}" 
          Header="Revert"> 
        <MenuItem.Icon> 
         <Image Source="{StaticResource ResourceKey=Revert}" 
           Height="16" 
           Width="16"/> 
        </MenuItem.Icon> 
       </MenuItem> 
      </ContextMenu> 
     </ContentControl.ContextMenu> 
    </ContentControl> 
</Grid> 
</UserControl> 

我想Binding为ListGrid冒泡到另一个视图模型和Command到本地视图模型。但CommandParameter应该是ContentControl。 日志中说:

System.Windows.Data Error: 4 : Cannot find source for binding with 
reference 'ElementName=currentContent'. BindingExpression:(no path); 
DataItem=null; target element is 'MenuItem' (Name=''); 
target property is 'CommandParameter' (type 'Object') 

回答

2

ContextMenuDataContext继承链,这就是为什么ElementName=currentContent无法找到。

看看这里的artificial inheritance context和使用类DataContextSpy

然后执行以下操作:

<UserControl> 
<UserControl.Resources> 
    <viewmodels:ListViewGridBaseViewModel x:Key="vm" /> 
    <local:DataContextSpy DataContext="{Binding ElementName=currentContent}" x:Key="Spy"> 
</UserControl.Resources> 
<Grid> 
    <ContentControl x:Name="currentContent" 
        Content="{Binding Path=ListGrid}" > 
     <ContentControl.ContextMenu> 
      <ContextMenu > 
       <MenuItem Command="{Binding Path=Save}" 
          CommandParameter="{Binding DataContext,Source={StaticResource Spy}}" 
          DataContext="{StaticResource ResourceKey=vm}" 
          Header="Save"> 
        <MenuItem.Icon> 
         <Image Source="{StaticResource ResourceKey=Save}" 
           Height="16" 
           Width="16"/> 
        </MenuItem.Icon> 
       </MenuItem> 
       <MenuItem Command="{Binding Path=Revert}" 
          DataContext="{StaticResource ResourceKey=vm}" 
          Header="Revert"> 
        <MenuItem.Icon> 
         <Image Source="{StaticResource ResourceKey=Revert}" 
           Height="16" 
           Width="16"/> 
        </MenuItem.Icon> 
       </MenuItem> 
      </ContextMenu> 
     </ContentControl.ContextMenu> 
    </ContentControl> 
</Grid> 
</UserControl> 
+0

完美,非常感谢你! – 2012-07-12 08:12:05

1

ContextMenu有一个单独的VisualTree,而不是用户控件的VisualTree的一部分,这就是为什么Elementname结合的不会工作。简单的解决方法使用ElementName绑定是在你的用户控件的添加该代码隐藏

NameScope.SetNameScope(currentContent, NameScope.GetNameScope(this)); 

或者你可以使用Enable ElementName Bindings with ElementSpy

+0

谢谢你的解释... 什么现在应该是“最佳实践”解决方案? – 2012-07-12 08:49:31

+0

这取决于你,你发现什么更容易?都有其好处并解决了这个问题。我宁愿只添加一行代码。 – akjoshi 2012-07-12 09:01:16

+0

我直接实施了间谍解决方案。这只是我的基础设施项目中的一个新类,以及xaml中的一个新名称空间,但那不是我问的原因。 我想知道哪种解决方案在性能等方面可能会更好。 – 2012-07-12 09:11:44