Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to track SelectedItem of DataGrid inside RowDetailsTemplate of another Datagrid

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!

like image 216
user2020014 Avatar asked Jan 29 '13 00:01

user2020014


1 Answers

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.

like image 61
user892381 Avatar answered Oct 21 '22 08:10

user892381