views:

1091

answers:

1

I was able to set up a WPF Datagrid, display a Northwind database table via linq-to-sql, and handle the TheDataGrid_RowEditEnding event so that it saves back the the database.

However, when a CustomerID was changed, it gets an error from the database which I handle, but how do I now either (1) rollback the Datagrid control or (2) refetch the original data from the database view LINQ-to-SQL (the refetching that I do below via LINQ seems to have some kind of caching, it doesn't refresh):

<Grid DockPanel.Dock="Bottom">
    <toolkit:DataGrid x:Name="TheDataGrid" 
                      AutoGenerateColumns="True"
                      RowEditEnding="TheDataGrid_RowEditEnding"/>
</Grid>



private void TheDataGrid_RowEditEnding(object sender, Microsoft.Windows.Controls.DataGridRowEditEndingEventArgs e)
{
    try
    {
        _db.SubmitChanges();
    }
    catch (Exception ex)
    {
        RefreshData();
        Message.Text = ex.Message;
    }
}

public void RefreshData()
{
    var customers = from c in _db.Customers
                    select c;
    TheDataGrid.ItemsSource = customers;
}

ANSWER:

Thanks Denis, I used your suggestions to get what I was after:

private void TheDataGrid_RowEditEnding(object sender, Microsoft.Windows.Controls.DataGridRowEditEndingEventArgs e)
{
    try
    {
        _db.SubmitChanges();
    }
    catch (Exception ex)
    {
        Customer customer = e.Row.Item as Customer;
        _db.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, customer);
        Message.Text = ex.Message;
    }
}
+3  A: 

First off, is it a requirement to be able to change the CustomerID? If that generates an error I would imagine that is not the case, so you should have that column marked as ReadOnly (IsReadonly="True" I believe).

Second, if you need to refresh an object from the database, you need to call the Refresh() on the datacontext, passing your object as a parameter. This will pull back the current values from the database.

Third, to deal with edit and rollbacks on whole object, the DataGrid supports the IEditableObject interface, which allows an object to expose local transaction-like methods (basically it makes internal copies of the data whenever BeginEdit is called and can revert the changes if needed). This is all a manual process, but it is an interface that has existed for a long time in Windows Forms if I am not mistaken, and you should be able to find tons of information about it (or someone better versed than me here can give you some examples).

You could implement that interface on your objects (through partial classes, since your objects are LinqToSQL classes, presumably generated by the designer).

Here's an article about the DataGrid and some options you have with it. It is a bit old, but it might give you some more pointers. Here is another, shorter one.

By the way, check out the WPF toolkit again, they just released a new version (March 2009 version) which might have more support for edition/validation than it used too.

Denis Troller