I don't know how to properly bind SelectedItem from a nested DataGrid. In the main DataGrid I have a binding like this:
SelectedItem="{Binding SelectedElement}"
and it work OK - if I select element in DataGrid property SelectedElement from MainVM class is set to the selected element. I have a similar binding in the nested DataGrid:
SelectedItem="{Binding SelectedMyItem}"
but it doesn't work at all - when I select item in nested DataGrid, property SelectedMyItem is still null.
My question:
How do I bind the SelectedMyItem property so that it is set after selecting item in the DataGrid?
I am not getting any bind error information from the IDE.
Here is a simple example showing my problem:
Classes:
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>
CodePudding user response:
Looks to me like you can modify the binding trigger to be on PropertyChanged
:
SelectedItem="{Binding SelectedMyItem, UpdateSourceTrigger=PropertyChanged}"
However, just a note on this:
When I run this in the debugger, the nested DataGrid selection fires before the outer DataGrid. Meaning the set
for SelectedMyItem
will fire before SelectedElement
. This is of course only when you are changing rows in the outer DataGrid.
The full .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>