Failed to track SelectedItem DataGrid inside RowDetailsTemplate of another Datagrid

Today I ran into this problem and could not find a solution. SelectedItem DataGrid that is inside the RowDetailsTemplate another DataGrid not set when I select the row inside the DataGrid that is inside the RowDetailsTemplate . (It's hard to explain clearly.)

Binding works correctly for lists. MainViewModel contains the ObservableCollection of MyItem objects and what the external DataGrid attached to.

The MyItem object contains an ObservableCollection of MyItem2 objects, and they are correctly bound to the internal DataGrid .

The MyItem object also has a SelectedItem2 property, which must be bound to the SelectedItem internal DataGrid , but will never be set.

By the way: I am using VS2012 and .Net 4.5.

Example:

MainWindow.xaml

 <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:wpfApplication1="clr-namespace:WpfApplication1" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <wpfApplication1:MainWindowViewModel x:Key="MainVm"/> </Window.Resources> <Grid DataContext="{StaticResource MainVm}"> <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Path=MyItem1s}"> <DataGrid.Columns> <DataGridTextColumn Header="Name" Width="*" Binding="{Binding Path=Name}"/> </DataGrid.Columns> <DataGrid.RowDetailsTemplate> <DataTemplate> <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Path=Item2s}" SelectedItem="{Binding Path=SelectedItem2}"> <DataGrid.Columns> <DataGridTextColumn Header="Item 2 Name" Width="130" Binding="{Binding Path=Name}"/> </DataGrid.Columns> </DataGrid> </DataTemplate> </DataGrid.RowDetailsTemplate> </DataGrid> </Grid> 

MainWindowViewModel

  public class MainWindowViewModel : ViewModelBase { public MainWindowViewModel() { for (int i = 0; i < 10; i++) { var item1 = new MyItem1(); item1.Name = i.ToString(); for (int j = 11; j < 20; j++) item1.Item2s.Add(new MyItem2() { Name = j.ToString() }); MyItem1s.Add(item1); } } private ObservableCollection<MyItem1> _myItem1S = new ObservableCollection<MyItem1>(); public ObservableCollection<MyItem1> MyItem1s { get { return _myItem1S; } set { _myItem1S = value; } } } 

MyItems ViewModels

  public class MyItem1 : ViewModelBase { private string _name; public string Name { get { return _name; } set { _name = value; OnPropertyChanged("Name"); } } private ObservableCollection<MyItem2> _item2S = new ObservableCollection<MyItem2>(); public ObservableCollection<MyItem2> Item2s { get { return _item2S; } set { _item2S = value; OnPropertyChanged("Item2s"); } } private MyItem2 _selectedItem2; public MyItem2 SelectedItem2 { get { return _selectedItem2; } set { _selectedItem2 = value; OnPropertyChanged("SelectedItem2"); } } } public class MyItem2 : ViewModelBase { private string _name; public string Name { get { return _name; } set { _name = value; OnPropertyChanged("Name"); } } } 

ViewModelBase

 public class ViewModelBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string property) { if(PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(property)); } } 

Any help would be greatly appreciated.

Thanks!

+4
source share
1 answer

Ahh that you just do not take advantage of onpropertychanged

try this on your datatemplate

 <DataTemplate DataType="{x:Type wpfApplication1:MyItem1}"> <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Item2s}" SelectedItem="{Binding Path=SelectedItem2, UpdateSourceTrigger=PropertyChanged}"> 

...... ...... ......

you need updateourcetrigger, I just create the code for your one binding, but you need to do this wherever you plan to update the value using the exchanged property

I usually use dependency properties, so you do not need to do this, but by studying the dependency properties and notifypropertychanged a bit, you can find the one you need.

+1
source

All Articles