为什么ContextMenu Command和CommandParameter在DataGrid中不起作用

时间:2017-04-21 13:28:32

标签: c# wpf mvvm binding datagrid

我有一个DataGird,然后它包含ExpanderContextMenu

DataGird正在分组。并且,ContextMenuExpander之间的DataGridItem不同。

但是,我想将MenuItem Command绑定到我的命令,并将DataGird的{​​{1}}或SelectedItems传递给SelectedIndex

但是不会调用此命令。即使它有效,当我调查一些方法得到目标时(例如set property Command),参数也不会通过。

所以,我想知道什么是正确的方法。

常规

tag

这项工作调用命令,但不能传递参数

<UserControl.DataContext>
    <vm:ViewModel x:Name="VM"/>
</UserControl.DataContext>
<Grid>
    <DataGrid x:Name="dg"
              ItemsSource="{Binding SourceData}"
              AutoGenerateColumns="False" 
              CanUserResizeColumns="False" 
              CanUserResizeRows="False"
              CanUserAddRows="False" 
              CanUserSortColumns="False"
              SelectionMode="Extended"
              RowHeaderWidth="0"
              GridLinesVisibility="Horizontal">
        <DataGrid.CellStyle>
            <Style TargetType="DataGridCell">
                <Setter Property="BorderThickness" Value="0"/>
                <!-- Remove the focus indication for the selected cell -->
                <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
            </Style>
        </DataGrid.CellStyle>
        <DataGrid.Columns>
            <DataGridTextColumn Header="No." Binding="{Binding No}" />
            <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
        </DataGrid.Columns>
        <DataGrid.GroupStyle>
            <GroupStyle>
                <GroupStyle.ContainerStyle>
                    <Style TargetType="{x:Type GroupItem}">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate>
                                    <Expander IsExpanded="False"  MouseRightButtonDown="Expander_MouseRightButtonDown" ButtonBase.Click="Expander_Click">
                                        <Expander.Header>
                                            <StackPanel Orientation="Horizontal">
                                                <StackPanel.ContextMenu>
                                                    <ContextMenu>
                                                        <MenuItem Header="Insert" InputGestureText="Ctrl+I" Command="{Binding InsertGroupItems"/>
                                                        <MenuItem Header="Remove" InputGestureText="Ctrl+D" Command="{Binding RemoveGroupItems"/>
                                                    </ContextMenu>
                                                </StackPanel.ContextMenu>
                                                <TextBlock Text="{Binding Name}"/>
                                                <TextBlock Text="{Binding ItemCount}"/>
                                                <TextBlock Text=" item(s)"/>
                                            </StackPanel>
                                        </Expander.Header>
                                        <ItemsPresenter>
                                            <ItemsPresenter.ContextMenu>
                                                <ContextMenu>
                                                    <ContextMenu>
                                                        <MenuItem Header="Insert" InputGestureText="Ctrl+I" Command="{Binding InsertSelectedItems" CommandParameter="{Binding ElementName=dg, Path=SelectedIndex}"/>
                                                        <MenuItem Header="Remove" InputGestureText="Ctrl+D" Command="{Binding RemoveSelectedItems" CommandParameter="{Binding ElementName=dg, Path=SelectedItems}"/>
                                                    </ContextMenu>
                                            </ItemsPresenter.ContextMenu>
                                        </ItemsPresenter>
                                    </Expander>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </GroupStyle.ContainerStyle>
            </GroupStyle>
        </DataGrid.GroupStyle>
    </DataGrid>
</Grid>

BTW,如何在获得参数时投射<DataGrid.GroupStyle> <GroupStyle> <GroupStyle.ContainerStyle> <Style TargetType="{x:Type GroupItem}"> <Style TargetType="{x:Type GroupItem}"> <Setter Property="Tag" Value="{Binding DataContext, RelativeSource={RelativeSource AncestorType=DataGrid}}" /> <Setter Property="ContextMenu"> <Setter.Value> <ContextMenu> <MenuItem Header="Insert" InputGestureText="Ctrl+I" Command="{Binding PlacementTarget.Tag.InsertSelectedItems, RelativeSource={RelativeSource AncestorType=ContextMenu}}" CommandParameter="{Binding ElementName=dg, Path=SelectedIndex}"/> <MenuItem Header="Remove" InputGestureText="Ctrl+D" Command="{Binding PlacementTarget.Tag.RemoveSelectedItems, RelativeSource={RelativeSource AncestorType=ContextMenu}}" CommandParameter="{Binding ElementName=dg, Path=SelectedItems}"/> </ContextMenu> </Setter.Value> </Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate> <Expander IsExpanded="False" MouseRightButtonDown="Expander_MouseRightButtonDown" ButtonBase.Click="Expander_Click"> <Expander.Header> <StackPanel Orientation="Horizontal"> <StackPanel.ContextMenu> <ContextMenu> <MenuItem Header="Insert" InputGestureText="Ctrl+I" Command="{Binding InsertGroupItems}"/> <MenuItem Header="Remove" InputGestureText="Ctrl+D" Command="{Binding RemoveGroupItems}"/> </ContextMenu> </StackPanel.ContextMenu> <TextBlock Text="{Binding Name}"/> <TextBlock Text="{Binding ItemCount}"/> <TextBlock Text=" item(s)"/> </StackPanel> </Expander.Header> <ItemsPresenter/> </Expander> </ControlTemplate> </Setter.Value> </Setter> </Style> </GroupStyle.ContainerStyle> </GroupStyle> </DataGrid.GroupStyle>

这不起作用

SelectedItems

所以,也许我有三个问题。

  1. private void Excute(object parameter) { IList list = parameter as IList; foreach (var item in list) { Remove((Data)item); } } 无效。

  2. ContextMenu未通过。

  3. 如何将CommandParameter转换为列表?

  4. 谢谢!

1 个答案:

答案 0 :(得分:2)

MenuItem中的ContextMenu无法使用ElementName绑定DataGrid,因为ContextMenuDataGrid属于Tag到不同的元素树。

您可以做的是将ItemsPresenter的{​​{1}}属性绑定到DataGrid,然后通过DataGrid绑定到PlacementTarget的属性ContextMenu

<ItemsPresenter Tag="{Binding RelativeSource={RelativeSource AncestorType=DataGrid}}">
    <ItemsPresenter.ContextMenu>
        <ContextMenu>
            <MenuItem Header="Insert2" InputGestureText="Ctrl+I"
                        DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
                        Command="{Binding DataContext.InsertSelectedItems}"
                        CommandParameter="{Binding SelectedIndex}"/>
            <MenuItem Header="Remove2" InputGestureText="Ctrl+D"
                        DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
                        Command="{Binding DataContext.RemoveSelectedItems}"
                        CommandParameter="{Binding SelectedItems}"/>
        </ContextMenu>
    </ItemsPresenter.ContextMenu>
</ItemsPresenter>
  

如何将SelectedItems转换为列表?

就像你在做。如果对SelectedItems的{​​{1}}属性的绑定有效,那么这应该有效:

DataGrid

修改

当然,绑定到private void Execute(object parameter) { IList list = parameter as IList; foreach (var item in list) { Remove((Data)item); } } 时也无法使用ElementName。试试这个:

CommandArgument