Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Datagrid.RowEditEnding doesn't return the update value

Tags:

c#

wpf

datagrid

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));
        }
    }
}
like image 950
Richie Avatar asked Apr 26 '13 12:04

Richie


2 Answers

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}"/>
like image 195
ChrisO Avatar answered Nov 06 '22 11:11

ChrisO


Workaround: update a static list of rows to be changed use another event to update the row(s) after the roweditending event

   private void datagrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
    {
        rows2change.Add(e.Row.GetIndex());
    }

    private void datagrid_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e)
    {
        if (rows2change.Count > 0)
        {
            saveMyData(rows2change[0]);
            rows2change.Remove(rows2change[0]);
        }
    }
like image 43
hackystack Avatar answered Nov 06 '22 12:11

hackystack