WPF Datagrid Checkbox bound to Nullable boolean column weirdness
December 15, 2011 Leave a comment
Case :
I am currently bussy with a project where i move a lot of data , some of this data is contained in bit fields in my database and i represent this in the UI with a checkbox in a datagrid everything worked fine untill i had a lightbulb moment the app gets its data through a WCF service , so i thought if the bit field is false i could better send a Nothing pointer ( NULL for sharpies ) as the XML would be a lot smaller ( a null is represented by not writing the tags in XML ) and thus my transfers should be faster so i changed the boolean fields in my Models to nullable booleans .
Problem :
After this change i noticed that my client app was actually slower ( huh ? ) , a quick look in the inmediate window showed the following message
“System.Windows.Data Error: 6 : ‘SystemConvertConverter’ converter failed to convert value ‘<null>’ (type ‘<null>’); fallback value will be used, if available. BindingExpression:Path=Stand; DataItem=’mErrorListing’ (HashCode=30844487); target element is ‘CheckBox’ (Name=”); target property is ‘IsChecked’ (type ‘Nullable`1’) InvalidCastException:’System.InvalidCastException: Null object cannot be converted to a value type at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider at MS.Internal.Data.SystemConvertConverter.Convert(Object o, Type type, Object parameter, CultureInfo culture) at System.Windows.Data.BindingExpression.ConvertHelper(IValueConverter converter, Object value, Type targetType, Object parameter, CultureInfo culture)'”
At first glance and after some Googling / Binging 🙂 i thought this was because my checkbox did not have the IsThreeState=”True” field set wich makes known to the WPF engine that we are dealing with a checkbox with three states True , False or NotSet ( Nothing a.k. Null ) , however setting this did not change a thing it still worked fine as before however the above message was printed in my debugger and i had the idea that it was actually slower as before ( because of the prints in the immediate window ofcourse as this slows the IDE )
Solution :
I Binged and Googled because there should be people outta there that have done this before , but nothing appeared of relevancy to my problem ,so i thought lets play with the binding behvaior
this is how it looked : <DataGridCheckBoxColumn x:Name=”Stnd” Binding=”{Binding Path=Stand}” Header=”Stnd” Width=”35″ IsThreeState=”True” /> so i enterd a , behind the last binding field value and looked at what intellisence presented to me as availlable properties to set at one moment i found the TargetNullValue property so i changed my line to <DataGridCheckBoxColumn x:Name=”Stnd” Binding=”{Binding Path=Stand,TargetNullValue=”}” Header=”Stnd” Width=”35″ IsThreeState=”True” /> , and eureka this worked no more error lines in my immediate window and my prog flew in speed as never before.
However now i got exactly what i requested from WPF i got a conversion to Null and a setter to Indeterminated of the grids checkbox ( wich shows the checkbox square filled with a color instead of a selection marker ) hmm 😦 do i actually want to present that to my users ? , after some peer reviews the answer was a big no , then i thought if this property does what its name says it shoud not be a problem at all to change the behavior so i ended up with this line <DataGridCheckBoxColumn x:Name=”Stnd” Binding=”{Binding Path=Stand,TargetNullValue=’False’}” Header=”Stnd” Width=”35″ IsThreeState=”True” /> that gives the exact behavior of my requirment if the bit field is set to True it shows my checkbox selected , if the bit field has a nothing / null pointer or a false it shows the checkbox deselected .