Add context menu in datagrid, how to get the select Item value

后端 未结 5 1216
说谎
说谎 2020-12-03 20:20

I am new in WPF programming with MVVM pattern. Now I have added the context menu in the datagrid. But, when I click the right mouse button, I don\'t know how to get the sele

相关标签:
5条回答
  • 2020-12-03 20:37

    bigworld12 has close to the right answer here, but it breaks if your context menu is templated. Try:

    DataGridRow row =
                ((sender as MenuItem)?.GetAncestors()
                   ?.FirstOrDefault(dpo => dpo.GetType() == typeof(ContextMenu)) as ContextMenu)
                   ?.PlacementTarget as DataGridRow;
    

    for the code-behind. I used nullable operators in case you somehow get here without the expected parent tree and target (maybe by triggering the context menu while off the grid.)

    0 讨论(0)
  • 2020-12-03 20:52

    I know this is an old question, but i wanted to share this very easy solution.

    XAML:

    <ContextMenu x:Key="MyRowMenu1" DataContext="{Binding PlacementTarget, RelativeSource={RelativeSource Self}}">
         <MenuItem Click="MenuItem_Click" Header="Add to Favourites"/>
         <MenuItem Header="Copy" >
         <MenuItem Header="Copy Name"/>
         <MenuItem Header="Copy ID" />
         <MenuItem Header="Copy IP Affffdress"/>
        </MenuItem>
    </ContextMenu>
    

    Code behind:

    Private Sub MenuItem_Click(sender As Object, e As RoutedEventArgs)
        Dim row As DataGridRow = DirectCast(DirectCast(DirectCast(sender, MenuItem).GetParentObject, ContextMenu).PlacementTarget, DataGridRow)
        'replace with what ever item you want
        Dim srvr As Server = DirectCast(row.Item, Server)
    
    End Sub
    
    0 讨论(0)
  • 2020-12-03 20:56

    This is a common problem in WPF. The solution is to utilise a Tag property in the item DataTemplate to hold the data item. First, let's add this part:

    <DataTemplate DataType="{x:Type YourDataTypeXmlNamespace:YourDataType}">
        <Border Tag="{Binding DataContext, RelativeSource={RelativeSource AncestorType={
    x:Type YourViewsXmlNamespace:YourViewWhereThisIsDeclared}}}">
            ...
        </Border>
    </DataTemplate>
    

    Now that we have access to the DataContext of the UserControl which can be found in the Tag property of each data object, let's bind to this from the ContextMenu... we do it using a handy property called PlacementTarget:

    <ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={
    RelativeSource Self}}">
        <MenuItem Header="Do Something" Command="{Binding YourCommandInYourViewModel}" 
    CommandParameter="{Binding YourCollection.CurrentItem}">
            ...
        </MenuItem>
    </ContextMenu>
    

    One thing to note is the YourCollection.CurrentItem property shown in the CommandParameter above. The CurrentItem property is a property that I added into my collection classes to bind to the SelectedItem properties of collection controls in the UI. If you don't have one of these, it's ok, but you will need a property that is bound to the SelectedItem property of your collection control for this to work. For my example, I have this:

    <ListBox ItemsSource="{Binding YourCollection}" SelectedItem="{Binding 
    YourCollection.CurrentItem}" />
    
    0 讨论(0)
  • 2020-12-03 20:57

    Expanding on Bolu's comment you could use SelectedItem to get the current item. Below is a quick example:

    <DataGrid ItemsSource="{Binding Source}" SelectedItem="{Binding SelectedItemProperty, Mode=TwoWay}">
        <DataGrid.ContextMenu>
            <ContextMenu>
                <MenuItem Command="{Binding MyCommand}" Header="MyCommand"/>
            </ContextMenu>
        </DataGrid.ContextMenu>
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" Binding="{Binding Key, Mode=TwoWay}" Width="1*"/>
            <DataGridTextColumn Header="Value" Binding="{Binding Value, Mode=TwoWay}" Width="3*"/>
        </DataGrid.Columns>
    </DataGrid>
    

    SelectedItem is now bound to SelectedItemProperty in the ViewModel.

    0 讨论(0)
  • 2020-12-03 20:57

    I think this is a similar case. I fixed it that way:

    <ContextMenu x:Key="rowContextMenu" Background="Transparent" >
    <MenuItem Header="{StaticResource LowPriority}" Style="{StaticResource menuStyle}"  
    CommandParameter="1" Click="ChangePriority"/>
    </ContextMenu>
    

    C# Code:

        private async void ChangePriority(object sender, RoutedEventArgs a)
        {
            MyTypeInRow row = (MyTypeInRow)(((MenuItem)sender).DataContext);
         ...
        }
    
       DataGrid.ItemsSource contains ObservableCollection<MyTypeInRow>. 
    
    0 讨论(0)
提交回复
热议问题