2012-07-12 2 views
2

WPF CommandCommandParameter에 대해 다른 Datacontext을 사용할 수 있습니까? Command 및 CommandParameter에 대한 다른 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> 

나는 ListGrid 다른 뷰 모델까지 버블의 Binding 로컬 뷰 모델에 Command합니다. 그러나 CommandParameterContentControl이어야합니다. LOG는 말하고있다 :

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

ContextMenu 넘김 DataContext 상속 체인을 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

완벽한을 사용할 수는, 대단히 감사합니다 코드 숨김 당신의 UserControl의이을 추가하는 것입니다! –

1

ContextMenu는 별도의 VisualTree을 가지고있는 UserControl의 VisualTree의 일부가 아니며 그건 왜 Elementname 바인딩의는하지 않습니다 작업. ElementName 바인딩을 사용하는 간단한 해결 방법은

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

아니면 Enable ElementName Bindings with ElementSpy

+0

설명을위한 와우 주셔서 감사합니다 ... 지금 "최고의 연습"솔루션은 무엇입니까? –

+0

당신이 더 쉽게 찾을 수있는 것은 당신에게 달려 있습니까? 모두 그들의 장점을 가지고 있으며 문제를 해결합니다. 단 한 줄의 코드를 추가하는 것을 선호합니다. – akjoshi

+0

나는 Spy 솔루션을 직접 구현했다. 그것은 나의 인프라 프로젝트에서 단지 하나의 새로운 클래스이고 xaml에서 하나의 새로운 네임 스페이스였습니다. 그러나 그것이 내가 묻는 이유가 아닙니다. 어떤 솔루션이 성능면에서 더 우수 할 지 궁금합니다. –