C# – Datagrid.RowEditEnding doesn’t return the update value

c++datagridwpf

I am new in C# WPF and is doing some very basic test on DataGrid. I can bind the data to the DataGrid but after I amend the row, I can received only old data. Can someone tell me what's wrong in my code? Here is my code:

XAML

<Window x:Class="abc.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid Name="dgEmployee" AutoGenerateColumns="False"
                  RowEditEnding="OnRowEditEnding">
            <DataGrid.Columns>
                <DataGridTextColumn Header="ID" Binding="{Binding EmpNo}"/>
                <DataGridTextColumn Header="Name" Binding="{Binding EmpName}"/>
                <DataGridTextColumn Header="Salary" Binding="{Binding Salary,
                    StringFormat='#,##0.00'}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

Code-behind

using System.Windows;

namespace abc
{
    public partial class MainWindow : Window
    {
        EmployeeList emp = new EmployeeList();


        public MainWindow()
        {
            InitializeComponent();
            dgEmployee.ItemsSource = emp;
        }

        private void OnRowEditEnding(object sender, System.Windows.Controls.DataGridRowEditEndingEventArgs e)
        {
            var _emp = e.Row.Item as Employee;
            MessageBox.Show(string.Format("updated record:\n{0}\n{1}\n{2}",
            _emp.EmpNo, _emp.EmpName, _emp.Salary));
        }
    }
}

and here is the Employee class:

using System.Collections.ObjectModel;

namespace abc
{
    public class Employee
    {
        private int _empNo;
        private string _empName;
        private decimal _salary;

        public Employee(int Id, string Name, decimal wage)
        {
            this._empNo = Id;
            this._empName = Name;
            this._salary = wage;
        }

        public int EmpNo { get { return _empNo; } set { _empNo = value; } }
        public string EmpName { get { return _empName; } set { _empName = value; } }
        public decimal Salary { get { return _salary; } set { _salary = value; } }
    }

    public class EmployeeList : ObservableCollection<Employee>
    {
        public EmployeeList()
            : base()
        {
            Add(new Employee(1, "Bart Simpson", (decimal)10));
            Add(new Employee(2, "Homer Simpson", (decimal)500));
            Add(new Employee(3, "Maggie Simpson", (decimal)200));
        }
    }
}

Best Solution

You need to change your WPF bindings to force an update back to your Employee class every time the property is changed. At the moment, by default, it only updates when the focus is lost which happens after the OnRowEditEnding event:

<DataGridTextColumn Header="ID" Binding="{Binding EmpNo, UpdateSourceTrigger=PropertyChanged}"/>