I ran into this problem earlier today and am unable to find a solution. The SelectedItem
of a DataGrid
that's inside the RowDetailsTemplate
of another DataGrid
is not being set when I select a row inside the DataGrid
that's inside the RowDetailsTemplate
. (Difficult to explain clearly.)
The bindings are all working properly for the lists. The MainViewModel contains an ObservableCollection
of MyItem
objects and that's what the outer DataGrid
binds to.
The MyItem
object contains an ObservableCollection
of MyItem2
objects and they get bound correctly to the inner DataGrid
.
The MyItem
object also has a property called SelectedItem2
which is supposed to be bound to the SelectedItem
of the inner DataGrid
but never gets set.
BTW: I'm 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 appreciated.
Thanks!
Ahh that's simple you aren't taking advantage of your 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 the updatesourcetrigger, i just put up code for your one binding but it needs to be done wherever you plan on updating the value using propertychanged
I usually use dependency properties so you don't need to do this, but doing a little research on dependency properties and notifypropertychanged you can find the one you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With