简体   繁体   中英

WPF Caliburn.Micro DataGrid Cell not updating before Event

I've got a test WPF application using Caliburn.Micro . I'm trying to build with a DataGrid that can be edited. The data will update the database when a cell / row gets updated.

The issue I'm running into though is that when my RowEditEnding event gets triggered. It passes the information in the row before the row was edited. I'm wondering how I can get the updated information passed to the function.

Any help would be appreciated. Relevant code below:

View:

<DataGrid x:Name="People"
          AutoGenerateColumns="False"
          CanUserReorderColumns="True"
          CanUserAddRows="True"
          AlternatingRowBackground="#dfdfdf"
          cal:Message.Attach="[Event RowEditEnding] = [Action SavePeopleEdit($this)]">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding FirstName}">
            <DataGridTextColumn.Header>
                <TextBlock Text="First"
                           ToolTip="This Persons First Name" />
            </DataGridTextColumn.Header>
        </DataGridTextColumn>
        <DataGridTextColumn Binding="{Binding LastName}">
            <DataGridTextColumn.Header>
                <TextBlock Text="Last"
                           ToolTip="This Persons Last Name" />
            </DataGridTextColumn.Header>
        </DataGridTextColumn>
        <DataGridTextColumn Binding="{Binding pNumber}">
            <DataGridTextColumn.Header>
                <TextBlock Text="Person Number"
                           ToolTip="This Persons pNumber" />
            </DataGridTextColumn.Header>
        </DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid> 

ViewModel:

using Caliburn.Micro;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;

namespace SqliteEncryptionTest.ViewModels
{

public class ShellViewModel : Screen
{
    public IObservableCollection<PersonModel> _people;
    public IObservableCollection<PersonModel> People {
        get { return _people; }
        set {
            _people = value;
            NotifyOfPropertyChange(() => People);
            } 
        }

        public void SavePeopleEdit(object sender)
        {
            if (People != null)
            {
            MessageBox.Show(People[3].LastName.ToString());
            }
        }

        public ShellViewModel()
        {
            LoadPeopleList();
        }

        private void LoadPeopleList()
        {
            People = new BindableCollection<PersonModel>(SqliteDataAccess.LoadPeople());
        }

    }
} 

在此处输入图片说明 I changed LastName to "Four", but it still shows the value to be "4".

It seems this was hinted at by Pavel Anikhouski in a comment on the original post, but I'll clarify this as an answer.

This is because RowEditEnding (and CellEditEnding) is executed just before the edit is committed (see this doc post ) so you can stop or edit change if you wish, you could grab the data that has been changed as shown in this SO answer

The best option however is to add UpdateSourceTrigger=PropertyChanged to the binding of each of the DataGrid columns you would like to have update as they are edited, this will update the model as each change is made, before RowEditEnding is executed.

<DataGrid x:Name="People"
          AutoGenerateColumns="False"
          cal:Message.Attach="[Event CellEditEnding] = [Action SavePeopleEdit($sender, $eventArgs)]">
<DataGrid.Columns>
    <!-- Will update while changed -->
    <DataGridTextColumn Header="First" Binding="{Binding FirstName, UpdateSourceTrigger=PropertyChanged}"/> 

    <!-- Will not update until after the change is committed -->
    <DataGridTextColumn Header="Last" Binding="{Binding LastName}"/> 
</DataGrid.Columns>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM