How to make a grid select the first record if it depends on another grid

2

I have a model, of the form:

public class A
{
   public ObservableCollection B col1;
}

Public Class B
{
   public int BA;
   public int BB;
   public ObservableCollection C;
}

public Class C
{
   public int CA;
   public int CB;
}

The first DataGrid is filled with the content of A, which is nothing more than a list of B elements.

<DataGrid x:Name="GrillaA" AutoGenerateColumns="False" IsReadOnly="True" SelectionMode="Single" ItemsSource="{Binding Mode=OneWay}">
   <DataGrid.Columns>
       <DataGridTextColumn Binding="{Binding BA}"/>
       <DataGridTextColumn Binding="{Binding BB}"/>
   </DataGrid.Columns>
 </DataGrid>

And then I have another grid, which is filled with the contents of the list that contains B (the list of objects C)

<DataGrid x:Name="GrillaB" AutoGenerateColumns="False" IsReadOnly="True" SelectionMode="Single" ItemsSource="{Binding SelectedItem.C, ElementName=GrillaA}">
   <DataGrid.Columns>
       <DataGridTextColumn Binding="{Binding CA}"/>
       <DataGridTextColumn Binding="{Binding CB}"/>
   </DataGrid.Columns>
</DataGrid>

All this is perfect .. except that under each grid I have some textbox that are filled with the content of the selected row in the grid ... For the case of the first grid, I have no problem, they are filled to perfection ..

The question is: when I select an item in the GrillaA, how do I select the first element of the GrillaB, in a MVVM model, in such a way that the fields below that grid are filled?

EDITING

I leave an example in git:

link

and no, beyond the first screen, on the second screen when selecting an item from the first grid, the second grid does not select the first item (because the selection property is executed twice)

    
asked by gbianchi 11.10.2017 в 17:56
source

1 answer

3

What you should do is add the property SelectedIndex with properties of your View Model in Grids B, both in GrillaA and GrillaB:

<DataGrid x:Name="GrillaA" AutoGenerateColumns="True" IsReadOnly="True" SelectionMode="Single" ItemsSource="{Binding Lista2}" SelectedIndex="{Binding SelectedA,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>

<DataGrid Grid.Column="1" x:Name="GrillaB" AutoGenerateColumns="True" IsReadOnly="True" SelectionMode="Single" ItemsSource="{Binding Lista2}" SelectedIndex="{Binding SelectedB,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>

Then in your ViewModel you add the two properties, and in the setter of the first one (to be executed when the selected index changes in GrillaA ) you can change the index of the other grid:

public class ViewModel:INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private int _selectedA=-1;
    private int _selectedB=-1;
    public int SelectedA
    {
        get { return this._selectedA; }
        set
        {
            this._selectedA = value;
            this.SelectedB = 0;
            NotifyPropertyChanged();
        }
    }

    public int SelectedB
    {
        get { return this._selectedB; }
        set
        {
            this._selectedB = value;
            NotifyPropertyChanged();
        }

    }

    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

This is a possible solution, there are others but I usually prefer this one.

Edited

I will explain another solution, since when using a property of the SelectedItem of the first grid to load the ItemsSource of the second, the first proposed solution did not work correctly.

First, we must add in the binding of ItemsSource of gridB the dependency property NotifyOnTargetUpdated to true , so that we are notified when the ItemsSource is changed. Afterwards, we simply subscribe to the event TargetUpdated of gridB and there we select the first index. Example:

XAML:

<DataGrid x:Name="dgListaB" ItemsSource="{Binding ListaB}"/>
<DataGrid x:Name="dgListaC" Grid.Row="2" ItemsSource="{Binding SelectedItem.ListaC, ElementName=dgListaB,NotifyOnTargetUpdated=True}" TargetUpdated="dgListaC_TargetUpdated"/>

Event handler:

private void dgListaC_TargetUpdated(object sender, DataTransferEventArgs e)
{
    this.dgListaC.SelectedIndex = 0;
}
    
answered by 11.10.2017 / 18:27
source