WPF - How to monitor datagrid selecteditem property change

1.6k views Asked by At

I am creating an application where I'm following the MVVM pattern (as best as I can), and I am using Prism to make that easier.

I have a view where the user can edit one cell, and in this cell, choose a value from a ComboBox. I would like to monitor when the selected row's ComboBox value changes. E.g. value is changed from "Bio" to "Pleje".

I don't know how to do this. I know there's the "PropertyChanged" event on the selected item, but where am I supposed to subscribe to it? Can't be done in the constructor as the selected item would be null.

enter image description here

    <DataGrid Grid.Column="0" Grid.Row="2" AlternationCount="2" AlternatingRowBackground="#cee8ff" CanUserAddRows="False" AutoGenerateColumns="False" ItemsSource="{Binding Path=Familier}" SelectedItem="{Binding ValgtFamilie, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">           
        <DataGrid.Columns>
            <DataGridTextColumn Header="Cpr" Binding="{Binding Path=CPR}" IsReadOnly="True"/>
            <DataGridTextColumn Header="Fornavn" Width="*"  Binding="{Binding Path=Fornavn}" IsReadOnly="True"/>
            <DataGridTextColumn Header="Efternavn" Width="*" Binding="{Binding Path=Efternavn}" IsReadOnly="True"/>

            <DataGridTemplateColumn Header="Forældre Type">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=ForældreTypeKategori}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding Path=DataContext.ForældreTypeKategorier, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" SelectedItem="{Binding Path=ForældreTypeKategori, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" IsSynchronizedWithCurrentItem="True"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>

ViewModel:

 private Familie valgtFamilie;
 public Familie ValgtFamilie
 {
    get { return valgtFamilie; }
    set { valgtFamilie = value; SetProperty(ref valgtFamilie, value); }
 }

Model:

internal class Familie : BindableBase
{
    private string cpr;
    public string CPR
    {
        get { return cpr; }
        set { cpr = value; SetProperty(ref cpr, value); }
    }

    private string fornavn;
    public string Fornavn
    {
        get { return fornavn; }
        set { fornavn = value; SetProperty(ref fornavn, value); }
    }

    private string efternavn;
    public string Efternavn
    {
        get { return efternavn; }
        set { efternavn = value; SetProperty(ref efternavn, value); }
    }

    private ForældreTypeKategori forældreTypeKategori;
    public ForældreTypeKategori ForældreTypeKategori
    {
        get { return forældreTypeKategori; }
        set { forældreTypeKategori = value; SetProperty(ref forældreTypeKategori, value); }
    }
}
2

There are 2 answers

0
Ouarzy On

First of all, do you really need to know when this property changed? Most of the time we just want to know the value when we validate the form, and we have this value thanks to DataBinding.

Now let's assume you really need it, the idea is to subscribe to the change of your property. For that I think this answer would help: MVVM in WPF - How to alert ViewModel of changes in Model... or should I?

0
mm8 On

I know there's the "PropertyChanged" event on the selected item, but where am I supposed to subscribe to it?

When a value is selected in the ComboBox in the view, the source property (ForældreTypeKategori) that is bound to the SelectedItem om the ComboBox will be set to the item in the ComboBox's ItemsSource that was selected.

So you could do whatever you want in the setter of this source property:

private ForældreTypeKategori forældreTypeKategori;
public ForældreTypeKategori ForældreTypeKategori
{
    get { return forældreTypeKategori; }
    set
    {
        forældreTypeKategori = value;
        SetProperty(ref forældreTypeKategori, value);

        //handle the change here...
    }
}

This is how MVVM works. You bind to source properties that the view sets.

By the way, it is considered a bad bad practice not to use English names of your class members such as properties and methods regardless of what your native language is.