anonymous-dev
anonymous-dev

Reputation: 2466

Call a Method when a property is changed in a DataGrid

I am trying to call a method when I update one of the fields in my DataGrid. Right now, I have tried multiple different options but none will even call a method or DelegateCommand I have created. Here is the code for my DataGrid:

<DataGrid x:FieldModifier="public" x:Name="Classes" CanUserAddRows="False" AutoGenerateColumns="False" CanUserResizeColumns="False" AlternatingRowBackground="LightBlue" ItemsSource="{Binding Classes, Mode=TwoWay}" SelectedItem="{Binding SelectedClass}" >
        <DataGrid.Columns>
            <DataGridTextColumn Width="200" Header="Class" Binding="{Binding Class, Mode=TwoWay}" IsReadOnly="True"/>
            <DataGridTextColumn Width="200" Header="Semester" Binding="{Binding Semester, Mode=TwoWay}" IsReadOnly="True"/>
            <DataGridTextColumn Width="200" Header="Date Due" Binding="{Binding Date_Due, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" />
            <DataGridTextColumn Width="200" Header="Importance" Binding="{Binding Importance, Mode=TwoWay}" IsReadOnly="True"/>
        </DataGrid.Columns>
    </DataGrid>

The Data Grid is bound to an Observable collection of an object I created. When the user updates the Date_Due field, I want to call a method in my ViewModel to update the database with the change. How would I go about doing this?

I am using an MVVM pattern so I don't have any code-behind.

Any help is appreciated.

Upvotes: 0

Views: 328

Answers (1)

Dennis Kuypers
Dennis Kuypers

Reputation: 556

You can wrap all of your ClassInfo-dataobjects (the object in the collection) with a thin layer that does your special logic (updating the DB).

// Your data object
public class ClassInfo
{
    public string Class { get; set; }
    public string Semester { get; set; }
    public DateTime Due { get; set; }
    public string Importance { get; set; }
}

// something that takes care of the update
public interface IDatabase
{
    void SendClassInfoUpdate(ClassInfo ci);
}

// a thin wrapper
public class ClassInfoViewModel
{
    IDatabase _db;
    ClassInfo _ci;

    public ClassInfoViewModel(IDatabase db, ClassInfo ci)
    {
        _db = db;
        _ci = ci;
    }

    public string Class
    {
        get => _ci.Class;
        set => _ci.Class = value;
    }
    public string Semester
    {
        get => _ci.Semester;
        set => _ci.Semester = value;
    }
    public DateTime Due
    {
        get => _ci.Due;
        set
        {
            _ci.Due = value;
            _db.SendClassInfoUpdate(_ci);
        }
    }
    public string Importance
    {
        get => _ci.Importance;
        set => _ci.Importance = value;
    }
}

The view doesn't know that it is dealing with your wrapper. This is also a fine way to prevent access on properties, add "view only" properties (calculated properties) and such. If you are doing INPC, you would have to proxy that as well.

You see a lot of code that only exists to proxy the calls to the inner object. That is what for example Castle.DynamicProxy can help you with. It provides an dynamic way to add such wrappers.

Upvotes: 1

Related Questions