【问题标题】:Why ContextMenu Command and CommandParameter are not working in DataGrid为什么 ContextMenu Command 和 CommandParameter 在 DataGrid 中不起作用
【发布时间】:2017-04-21 13:28:31
【问题描述】:

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

这个DataGird 正在分组。而且,ExpanderDataGridItem 之间的 ContextMenu 是不同的。

但是,我想将MenuItem Command 绑定到我的命令,并将DataGirdSelectedItemsSelectedIndex 传递给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>

这个工作调用命令,但是不能传参数

<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);
    }
}

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

  1. ContextMenu 不起作用。

  2. CommandParameter 没有通过。

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

谢谢!

【问题讨论】:

    标签: c# wpf mvvm binding datagrid


    【解决方案1】:

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

    您可以做的是将ItemsPresenterTag属性绑定到DataGrid,然后通过ContextMenuPlacementTarget绑定到DataGrid的属性:

    <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 转换为列表?

    就像你正在做的那样。如果绑定到DataGridSelectedItems 属性有效,这应该可以工作:

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

    编辑:

    当然,在绑定到CommandArgument 时也不能使用ElementName。试试这个:

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

    【讨论】:

    • 感谢您的回答。我尝试您的代码不起作用,如果我在&lt;GroupStyle.ContainerStyle&gt; 中按样式定义TagContextMenu。这很困惑。我会更新我的代码。
    • 它肯定对我有用。我不知道“这很混乱”是什么意思。
    • 对不起,我不明白你的意思。也许你应该再读一次我的回答。
    • 当然,绑定CommandArgument时也不能使用ElementName。
    • 哦.. 也许你可以看到我的更新代码。我将再次尝试使用一个空项目。
    猜你喜欢
    • 2014-04-22
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多