DataGrid RowEditEndED

Jan 30, 2009 at 9:30 AM
Hi All,

I have a business object bound to my DataGrid and need to know when a row has completed editing and the datasource object is updated so I can save. I can only find a RowEditEnding though which is too early to save. I ideally need a RowEditEnded so I can be sure the datasource object is updated and I can save the changes.

Any ideas?

Jan 30, 2009 at 12:13 PM
See this thread and this thread
Jan 30, 2009 at 12:49 PM
Option 1 looks like what I am after, and code compiles find. But the OnDataGridSourceUpdated event does not fire at all? Is there a specific place where you have to hook the event handler? I am doing it on on the page load.
Feb 2, 2009 at 6:48 AM
Any ideas here guys? How do I get the SourceUpdated event to fire in option 1 above? This has be really stuck, and delaying my release to the client.

PLEASE help :)
Feb 2, 2009 at 7:51 AM
Okay, some small progress, but in the wrong direction. I am managing to get the TargetUpdated event to fire, but NOT SourceUpdated.

My XAML looks like this
<dg:DataGridTemplateColumn Header="Cost (Ex)" Width="120">
      <Label Content="{Binding CostEx, NotifyOnSourceUpdated=True}" ContentStringFormat="{}{0:0.00}" HorizontalContentAlignment="Right" Margin="0" />
      <TextBox Text="{Binding CostEx, NotifyOnSourceUpdated=True}" Margin="0" />

If I changed NotifyOnSourceUpdated to NotifyOnTargetUpdated (and the respective code behind), then the TargetUpdated event is fired. For the source though, nothing is fired at all.

Code behind looks like this...

public Stock()

  Binding.AddTargetUpdatedHandler(StockPricingGrid, OnDataGridSourceUpdated);

void OnDataGridSourceUpdated(object sender, DataTransferEventArgs e)
  FMS.DAL.StockPricingCollection items = (FMS.DAL.StockPricingCollection)StockPricingGrid.ItemsSource;
  if (items == null)
Feb 2, 2009 at 7:57 AM
Sorry for confusion people. The line above..
Binding.AddTargetUpdatedHandler(StockPricingGrid, OnDataGridSourceUpdated);

Should read
Binding.AddSourceUpdatedHandler(StockPricingGrid, OnDataGridSourceUpdated);

I forgot to change it all back when I posted the message here.

Feb 2, 2009 at 8:37 AM
You can use a RowValidationRule with ValidationStep="CommittedValue". That should do what you want (I had the same problem earlier, and CommittedValue causes the validator to invoke when the data has been committed to the bound object).
Feb 2, 2009 at 8:41 AM
Thanks mikj. How do I implement a RowValidationRule?
Feb 2, 2009 at 8:55 AM
Implement System.Windows.Controls.ValidationRule and then in the XAML:

<Page ... xmlns:yourns="clr-namespace:YourNamespace">
        <tk:DataGrid ...>
                    <yourns:YourValidatorClass ValidationStep="CommittedValue" />

What I have done is simply to let the validator attempt a commit to the data layer, and return a success or failure status based on the result of that.
Feb 2, 2009 at 9:21 AM
Great stuff. Your trick is working :)

What I did, was implement the IDataErrorInfo interface on my DAL class, then call Save() in the string Error property.

This works and gets the job done, but data is saved everytime a cell is committed which is a load of server traffic. Is there a way to handle validation only when focus leaves a row?

Thanks a lot for your tips mikj. At least now I have something working.

In the xaml, I just had to set..
  <DataErrorValidationRule ValidationStep="CommittedValue"/>

Feb 2, 2009 at 9:29 AM
I'm not sure I understand what you are doing at this point. Adding a row validation rule requires no changes to your business object class (unless you choose to implement ValidationRule in it, but I prefer to keep that in a separate *Validator class so it is clear what class performs what function) and it only fires on row exit, not when moving between columns. You also "should not" need the SourceUpdated handler, but I am not too sure exactly when that event fires and am not in a position to look into that right now.

Try setting a breakpoint in your validator - it should fire _only_ on row exit. If that is the case, your problem is somewhere in the surrounding code, and your best bet might be to put breakpoints there and look at stack traces. If a RowValidationRule fires when you move between cells, I am at a total loss - I can definitely say that it doesn't for me, and even the name implies that it is not supposed to.