0

I am working on an application which is totally based on MVVM. I am facing a binding problem.

<ListView ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}},Path=DataContext.CurrentSecurityList}">
<ListView.ContextMenu>
 <ContextMenu>
  <MenuItem Header="Remove" Command="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type UserControl}},Path=DataContext.RemoveSecurity}"/>
 </ContextMenu>
</ListView.ContextMenu> 

ListView binding is working absolutely fine in this code but the problem comes when it comes to MenuItem Command Binding. Can someone explain what i am doing wrong over here.

Ahmad.Masood
  • 1,289
  • 3
  • 21
  • 40
  • 1
    "but the problem comes" doesn't help, what problem ? For binding issues, please take a look at your "output" window in Visual Studio, and copy/paste the binding errors it shows. – ken2k Jul 02 '13 at 12:36
  • ContextMenu binding is a well known case - check this post as one of the many others http://stackoverflow.com/questions/1013558/elementname-binding-from-menuitem-in-contextmenu – sll Jul 02 '13 at 12:37
  • Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.UserControl', AncestorLevel='1''. BindingExpression:Path=DataContext.RemoveSecurity; DataItem=null; target element is 'MenuItem' (Name=''); target property is 'Command' (type 'ICommand') – Ahmad.Masood Jul 02 '13 at 12:38

2 Answers2

2

ContextMenu works on different visual tree so it is not possible to bind it like that. You need to find ContextMenu ancestor and refer to its PlacementTarget.DataContext to retrieve your command. Try something like this:

<MenuItem Header="Remove" Command="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ContextMenu}},Path=PlacementTarget.DataContext.RemoveSecurity}"/>
dkozl
  • 32,814
  • 8
  • 87
  • 89
2

Put a Tag in ListView to connect its ancestor to its ContextMenu:

<ListView ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}},Path=DataContext.CurrentSecurityList}"
              Tag="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}">
        <ListView.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Remove" Command="{Binding PlacementTarget.Tag.DataContext.RemoveSecurity, RelativeSource={RelativeSource 
                                AncestorType=ContextMenu}}"/>
            </ContextMenu>
        </ListView.ContextMenu>
    </ListView>
Bill Zhang
  • 1,909
  • 13
  • 10
  • Thanks It Worked. Can you please explain why we have to define Tag in this way? – Ahmad.Masood Jul 02 '13 at 12:58
  • 1
    MenuItem can find ListView through ContextMenu's PlacementTarget. However, it could not find further. If the source object of Command binding is not on ListView (in your case, it is on ListView's ancestor's DataContext), you have to use Tag like a bridge. – Bill Zhang Jul 02 '13 at 13:03