Context Menu items command binding WPF using MVVM

后端 未结 5 508
眼角桃花
眼角桃花 2021-01-01 04:56

I know this question has been asked many times in different ways in many websites and also in StackOverFlow but all the answers I found are not helping me ot to be precise I

相关标签:
5条回答
  • 2021-01-01 05:28
    <MenuItem Header="Cut" Command="{Binding Path=PlacementTarget.DataContext.CutCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
    
    0 讨论(0)
  • 2021-01-01 05:30

    I usually instantiate my view model as static resource in my view:

    <UserControl x:Class="My.Namespace.MySampleView" ...> 
        <UserControl.Resources> 
            <viewModels:MySampleViewModel x:Key="ViewModel" /> 
        </UserControl.Resources> 
    

    Then you can easily reference any property of your view model even if the current binding context is not the view model:

    <ContextMenu x:Key="columnHeaderMenu">
        <MenuItem Command="{Binding MyCommand, Source={StaticResource ViewModel}}" />
    </ContextMenu>
    

    For more information, have a look at my article Recommendations and best practices for implementing MVVM and XAML/.NET applications.

    0 讨论(0)
  • 2021-01-01 05:31

    I had the same issue. The command bindings stopped working once I moved them to the ViewModel from code behind. And in the viewmodel I had to change my ICommand from RoutedCommand to DelegateCommand. I was able to get it working in the following way -

    Add Opened eventhandler to your context menu -

    <ContextMenu x:Key="columnHeaderMenu" Opened="ContextMenu_Opened">
        <MenuItem Command="{Binding CutCommand}" Header="Test" />
        <MenuItem Header="Copy"/>
        <MenuItem Header="Paste"/>
    </ContextMenu>
    

    In the code behind, you would assign your ViewModel to the context menu's DataContext -

    private void ContextMenu_Opened(object sender, RoutedEventArgs e)
    {
        ContextMenu menu = sender as ContextMenu;
        menu.DataContext = _vm;
    }
    
    0 讨论(0)
  • 2021-01-01 05:37

    You have two options.
    Note: the code samples I added here a similar, but not same as your samples.

    Move the definition of the ContextMenu inside the DataGrid defintion as follows:

    <WpfToolkit:DataGrid
       x:Name="DataGrid_Standard"
       IsSynchronizedWithCurrentItem="True"
       Background="Transparent" 
       ItemsSource="{Binding FullGridData}" 
       ColumnHeaderStyle="{StaticResource DefaultColumnHeaderStyle}">
       <WpfToolkit:DataGrid.ContextMenu>
           <ContextMenu>
               <MenuItem Command="{Binding CutCommand}" Header="Test" />
               <MenuItem Header="Copy"/>
               <MenuItem Header="Paste"/>
           </ContextMenu>
       </WpfToolkit:DataGrid.ContextMenu>
    </WpfToolkit:DataGrid>
    

    Or better add a CommandReference to your Resources and set the Command in the MenuItem to a StaticResource as follows:

    <Window.Resources>
        <c:CommandReference x:Key="MyCutCommandReference" Command="{Binding CutCommand}" />
    
        <ContextMenu x:Key="columnHeaderMenu">
            <MenuItem Command="{StaticResource MyCutCommandReference}" Header="Test" />
            <MenuItem Header="Copy"/>
            <MenuItem Header="Paste"/>
        </ContextMenu>
    
        <Style TargetType="{x:Type Primitives:DataGridColumnHeader}" x:Key="DefaultColumnHeaderStyle">
            <Setter Property="ContextMenu" Value="{DynamicResource columnHeaderMenu}" />
        </Style>
    
    </Window.Resources>
    
    <WpfToolkit:DataGrid
       x:Name="DataGrid_Standard"
       IsSynchronizedWithCurrentItem="True"
       Background="Transparent" 
       ItemsSource="{Binding FullGridData}" 
       ColumnHeaderStyle="{StaticResource DefaultColumnHeaderStyle}"/>
    
    0 讨论(0)
  • 2021-01-01 05:42

    Something in your code (or the version of WPF being used at the time(?)) is overcomplicating things. I am able to bind such as

    <DataGrid AutoGenerateColumns="True"
            Name="myGrid"
            ItemsSource="{Binding Orders}">
        <DataGrid.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Copy" Command="{Binding CopyItem}" />
                <MenuItem Header="Delete" Command="{Binding DeleteItem}" />
            </ContextMenu>
        </DataGrid.ContextMenu>
    </DataGrid>
    

    Where the command is setup like this:

    VM.DeleteItem 
         = new OperationCommand((o) => MessageBox.Show("Delete Me"),
                                (o) => (myGrid.SelectedItem as Order)?.InProgress == false );
    

    0 讨论(0)
提交回复
热议问题