DataGrid 上下文菜单未正确绑定

问题描述 投票:0回答:1

我有一个

DataGrid
,我试图向其中添加一个带有命令绑定的
ContextMenu
ContextMenu
的定义如下:

<DataGrid Grid.Row="6" Grid.Column="0" Grid.ColumnSpan="4" Name="DgResults" Margin="10, 25, 10,10" AutoGenerateColumns="False">
            <DataGrid.ContextMenu>
            <ContextMenu>
                <MenuItem Command="{Binding GenerateDutyCycleCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
                          Header="Generate DC"></MenuItem>
            </ContextMenu>
            </DataGrid.ContextMenu>
</DataGrid>

Window
的代码隐藏中,我定义了命令属性:

        private ICommand? _command;

        public ICommand GenerateDutyCycleCommand
        {
            get
            {
                var m = 0;
                return _command ??= new CommandHandler(GenerateDutyCycle, CanExecute);
            }
        }

        public void GenerateDutyCycle()
        {
            MessageBox.Show("Command Executed");
            var selectedItem = DgResults.SelectedItem;
            var p = 0;
        }

        public bool CanExecute()
        {
            return Results.Count > 0;
        }

在 XAML 中,如果我右键单击

GenerateDutyCycleCommand
并选择 转到定义,它会按预期转到属性,所以似乎一切都是正确的。

当我运行代码时,总是显示

ContextMenu
并且永远不会命中
CanExecute
方法。同样,如果我单击菜单项,则永远不会点击
GenerateDutyCycle
方法(或显示消息框)。我尝试了几次修改(例如,将
DataContext
MenuItem
设置为
Window
),但没有成功。

我在运行时还看到存在 XAML 绑定失败,其中指出 找不到源:RelativeSource FindAncestor、AncestorType='System.Windows.Window'、AncestorLevel='1'。我不清楚为什么这个绑定会失败,如果它可以识别定义(通过Go To Definition)。

任何帮助/指导将不胜感激。短暂性脑缺血发作。

更新:我能够通过从ContextMenu中删除

DataGrid
定义并添加样式(到
Window.Resources
)来使这个
部分
工作,如下所示:

        <Style TargetType="{x:Type DataGridRow}">
            <Setter Property="Tag" 
                    Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, 
                            Path=DataContext}"/>
            <Setter Property="ContextMenu">
                <Setter.Value>
                    <ContextMenu DataContext="{Binding PlacementTarget.Tag, 
                                               RelativeSource={RelativeSource Self}}">
                        <MenuItem Command="{Binding GenerateDutyCycleCommand}"
                                  Header="Generate DC"></MenuItem>
                    </ContextMenu>
                </Setter.Value>
            </Setter>
        </Style>

使用这种样式,当

DataGrid
中没有结果时,
ContextMenu
不会显示。但是,
CanExecute
GenerateDutyCycle
方法中的断点仍然没有被命中。另外,当有结果并单击菜单项时,不会显示
MessageBox

c# wpf data-binding icommand
1个回答
0
投票

我设法通过添加

ContextMenu
作为
DataGrid
的资源,然后将其分配在行的样式中,如下所示找到解决方案:

            <DataGrid.Resources>
                <ContextMenu x:Key="CtxDataGrid">
                    <ContextMenu.Items>
                        <MenuItem
                            Header="Generate DC"
                            Command="{Binding GenerateDutyCycleCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"
                            CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource  Mode=FindAncestor, AncestorType=DataGrid}}"/>
                    </ContextMenu.Items>
                </ContextMenu>
            </DataGrid.Resources>
            <DataGrid.RowStyle>
                <Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}">
                    <Setter Property="ContextMenu" Value="{StaticResource CtxDataGrid}" />
                </Style>
            </DataGrid.RowStyle>
© www.soinside.com 2019 - 2024. All rights reserved.