Wpf:如何从嵌套的 DataGrid 中绑定 SelectedItem

Wpf: How to bind SelectedItem from nested DataGrid

我不知道如何从嵌套的 DataGrid 中正确绑定 SelectedItem。在主 DataGrid 中,我有这样的绑定:

SelectedItem="{Binding SelectedElement}"

它工作正常 - 如果我 select element 在 DataGrid 属性 SelectedElement 来自 MainVM class 设置为 selected 元素。 我在嵌套的 DataGrid 中有一个类似的绑定:

SelectedItem="{Binding SelectedMyItem}"

但它根本不起作用 - 当我在嵌套 DataGrid 中 select item 时,属性 SelectedMyItem 仍然是 null.

我的问题:
我如何绑定 SelectedMyItem 属性 以便在 DataGrid 中 selecting 项目之后设置它?

我没有从 IDE 获得任何绑定错误信息。

这是一个简单的例子来说明我的问题:

类:

using System.Collections.ObjectModel;

namespace NesteGridMVVM
{
    public class MyItem
    {
        public string MyItemName { get; set; }
    }
    
    //======================================================================
    
    public class Element
    {
        private MyItem _selectedItem;

        public string ElementName { get; set; }
        public ObservableCollection<MyItem> MyItemsList { get; set; } = new ObservableCollection<MyItem>();

        //Binded to SelectedItem in nested DataGrid
        public MyItem SelectedMyItem
        {
            get => _selectedItem;
            set
            {
                _selectedItem = value;

                //Show, if MyItem was selected - it not work.
                System.Diagnostics.Debug.Print($"Selected MyItem: {_selectedItem.MyItemName}");
            }
        }
    }
    
    //======================================================================

    public class MainVM
    {
        private Element _selectedElement;

        public ObservableCollection<Element> ElementsList { get; set; } = new ObservableCollection<Element>();

        //Binded to SelectedItem in main DataGrid
        public Element SelectedElement
        {
            get => _selectedElement;
            set
            {
                _selectedElement = value;

                //Show, if Element was selected - it works OK
                System.Diagnostics.Debug.Print($"{_selectedElement.ElementName}");
            }
        }

        //ctor - populate view model
        public MainVM()
        {
            Element elem1 = new Element() { ElementName = "element-01" };
            Element elem2 = new Element() { ElementName = "element-02" };

            elem1.MyItemsList.Add(new MyItem() { MyItemName = "item-A" });
            elem1.MyItemsList.Add(new MyItem() { MyItemName = "item-B" });
            elem2.MyItemsList.Add(new MyItem() { MyItemName = "item-C" });

            ElementsList.Add(elem1);
            ElementsList.Add(elem2);
        }
    }
}

XAML:

<Window x:Class="NesteGridMVVM.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:NesteGridMVVM"
        mc:Ignorable="d"
        Title="MainWindow" Height="550" Width="600">

    <Window.DataContext>
        <local:MainVM /> 
    </Window.DataContext>

    <DataGrid
        x:Name="MainDG"
        ItemsSource="{Binding ElementsList}"
        AutoGenerateColumns="True"
        SelectedItem="{Binding SelectedElement}"
        RowDetailsVisibilityMode="Visible">
        <DataGrid.RowDetailsTemplate>
            <DataTemplate>
                <DataGrid
                    x:Name="NestedDG"
                    ItemsSource="{Binding MyItemsList}"
                    AutoGenerateColumns="True"
                    SelectedItem="{Binding SelectedMyItem}">
                </DataGrid>
            </DataTemplate>
        </DataGrid.RowDetailsTemplate>
    </DataGrid>
</Window>

在我看来,您可以将绑定触发器修改为开启 PropertyChanged:

SelectedItem="{Binding SelectedMyItem, UpdateSourceTrigger=PropertyChanged}"

但是,请注意:

当我在调试器中 运行 这样做时,嵌套的 DataGrid 选择在外部 DataGrid 之前触发。这意味着 SelectedMyItemset 将在 SelectedElement 之前触发。这当然仅在您更改外部 DataGrid 中的行时才会发生。

完整.xaml:

<Window x:Class="NesteGridMVVM.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:NesteGridMVVM"
        mc:Ignorable="d"
        Title="MainWindow" Height="550" Width="600">

    <Window.DataContext>
        <local:MainVM /> 
    </Window.DataContext>

    <DataGrid
        x:Name="MainDG"
        ItemsSource="{Binding ElementsList}"
        AutoGenerateColumns="True"
        SelectedItem="{Binding SelectedElement}"
        RowDetailsVisibilityMode="Visible">
        <DataGrid.RowDetailsTemplate>
            <DataTemplate>
                <DataGrid
                    x:Name="NestedDG"
                    ItemsSource="{Binding MyItemsList}"
                    AutoGenerateColumns="True"
                    SelectedItem="{Binding SelectedMyItem, UpdateSourceTrigger=PropertyChanged}">
                </DataGrid>
            </DataTemplate>
        </DataGrid.RowDetailsTemplate>
    </DataGrid>
</Window>