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

标签 c# wpf mvvm binding datagrid

我有一个 DataGird ,则包括 ExpanderContextMenu .

这个DataGird正在分组。而且,它有不同的ContextMenu Expander之间和 DataGridItem .

但是,我想绑定(bind) MenuItem Command到我的命令,并通过 DataGirdSelectedItemsSelectedIndexCommand .

但是这个命令没有被调用。即使它有效,当我调查某些方法得到目标时,参数也不会通过(如 set property 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>

这个工作调用命令,但不能传递参数
<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什么时候得到参数?

不行
private void Excute(object parameter)
{
    IList list = parameter as IList;
    foreach (var item in list)
    {
        Remove((Data)item);
    }
}

所以,也许我有三个问题。
  • ContextMenu不工作。
  • CommandParameter不通过。
  • 如何转换 SelectedItems列表?

  • 谢谢!

    最佳答案

    一个 MenuItemContextMenu不能使用 ElementName绑定(bind)到 DataGrid因为 ContextMenuDataGrid属于不同的元素树。

    你可以做的是绑定(bind) Tag ItemsPresenter 的属性(property)到DataGrid然后绑定(bind)到 DataGrid 的属性通过PlacementTargetContextMenu :

    <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>
    

    How to convert SelectedItems to a list?



    就像你正在做的那样。如果绑定(bind)到 SelectedItems,这应该可以工作。 DataGrid 的属性(property)作品:
    private void Execute(object parameter)
    {
        IList list = parameter as IList;
        foreach (var item in list)
        {
            Remove((Data)item);
        }
    }
    

    编辑:

    当然你不能使用 ElementName当绑定(bind)到 CommandArgument任何一个。试试这个:
    <Style TargetType="{x:Type GroupItem}">
        <Setter Property="Tag" Value="{Binding Path=., RelativeSource={RelativeSource AncestorType=DataGrid}}" />
        <Setter Property="ContextMenu">
            <Setter.Value>
                <ContextMenu>
                    <MenuItem Header="Insert" InputGestureText="Ctrl+I"
                              Command="{Binding PlacementTarget.Tag.DataContext.InsertSelectedItems, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
                              CommandParameter="{Binding PlacementTarget.Tag.SelectedIndex, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
                    <MenuItem Header="Remove" InputGestureText="Ctrl+D"
                              Command="{Binding PlacementTarget.Tag.DataContext.RemoveSelectedItems, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
                              CommandParameter="{Binding PlacementTarget.Tag.SelectedItems, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
                </ContextMenu>
            </Setter.Value>
        </Setter>
    

    关于c# - 为什么 ContextMenu Command 和 CommandParameter 在 DataGrid 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43544011/

    相关文章:

    c# - 在 Silverlight 中同步填充自定义控件的 DependencyProperties

    javascript - 对 .aspx 和 .html 感到困惑

    c# - 使用 Microsoft SDK 或 ManagementObjectSearcher 确定 Kinect 是否已插入

    wpf - 我可以在运行时将 XML/XAML 转换为 WPF 控件吗?

    C# WPF ComboBox - 允许每个列表只选择一次项目

    c# - DevExpress MVVM - 共享 ViewModel 和 EventToCommand

    c# - 使用 Process 类的 C# 应用程序中的 ffmpeg - 用户提示未显示在标准错误中

    c# - 立即更新 toolStripStatusLabel

    c# - 具有水平对齐的可调整大小对象的列表框

    c# - 如何将 ListBox 的 Visibility 绑定(bind)到 ApplicationBar 按钮?