I am binding two instances of a XamNumericEditor to a DataRow. Both editors bind to columns of type System.Decimal. The columns both accept DBNull.Value. If I remove all text from the editor, I would like the value to be set to DBNull. Even though as far as I can tell both instances are declared in the same way via XAML and both columns are set up exactly in the same way, one of the editors behaves correctly and one does not. The one that does not, when the input string is empty, prints out the following error in the Debug window in VS.
System.Windows.Data Error: 8 : Cannot save value from target back to source. BindingExpression:Path=[ColumnName]; DataItem='Row' (HashCode=47250101); target element is 'XamNumericEditor' (Name='txt); target property is 'Value' (type 'Object') TargetInvocationException:'System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentException: Cannot set Column 'ColumnName' to be null. Please use DBNull instead.
Essentially, one of the instances seems to be passing null back to the binding, instead of DBNull when the input string is String.Empty.
The XAML for both is exactly the same, save for the column names:
<Editors:XamNumericEditor Style="{StaticResource styl_NumTextBox}" MinWidth="70" MaxWidth="70" x:Name="txt" ValueType="{x:Type sys:Decimal}" Mask="{}{double:-5.3}" Value="{Binding Path=[ColumnName], UpdateSourceTrigger=PropertyChanged}" />
Is there a way to force the editor to pass DBNull.Value on an empty string? Do I have to overwrite the TextToDisplayStringConverter? If so, how do I apply the mask to the value?
I installed a converter on the Value={Binding}. Turns out that the editor actually does return DBNull.Value, not null. For some reason, the binding is still failing. Here is the stack trace from the trace.
at System.Data.DataRow.set_Item(DataColumn column, Object value) at System.Data.DataRow.set_Item(String columnName, Object value) --- End of inner exception stack trace --- at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture) at MS.Internal.Data.PropertyPathWorker.SetValue(Object item, Object value) at MS.Internal.Data.ClrBindingWorker.UpdateValue(Object value) at System.Windows.Data.BindingExpression.UpdateSource(Object value)'
Ugh, http://connect.microsoft.com/VisualStudio/feedback/details/539721/binding-converter-returns-dbnull-value-but-saved-as-null