WPF Datagrid Checkbox bound to Nullable boolean column weirdness

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 .

 

 

Advertisements

VB.Net and MVVM

 MVVM

Microsoft has revisited the original presentation Model by a proposition of Martin Fowler this revission named MVVM is the perfect aproach for WPF and Silverlight as it was specifically designed for them

If you built apps with the Windows Presentation Framework ( WPF ) , Silverlight or for Windows Phone 7 you should sure consider adopting the Model View ViewModel ( MVVM ) as this design pattern is specifically handy to deall with  XAML UI elements in a clear way .

History

In 1974 EWD (*) wrote a paper called “On the role of scientific thought” , this was the first document that discussed the concept of SoC “…The Seperation Of Concerns, [is] the only availlable technique for efective ordering of one`s thoughts , that i know of.”

In 1989 Chris Reade went a step further and described the tasks “1. describe what is to be computed 2. Organize the computation sequencing into small steps 3. Organize memory management during the computation”

Moving fast forward Martin fowler and Eric Evans started to discuss design patterns related to contextual design leading to the current concept of SoC soon there were patterns and concepts like Domain Driven Design , Unit of Work and manny other  approaches and UI patterns like MVC , MVP and MVVM .

Layers

MVVM forces you to divide application code into different Layers  and Tiers

Model:  the model refers to either  an object model that represents the real state content , or  the data access layer that represents that content

View: the view refers to all elements displayed by the GUI .

ViewModel: the ViewModel is a “Model of the View” meaning it is an abstraction of the View that also serves in data binding between the View and the Model.  The ViewModel exposes public properties, commands, and abstractions. The ViewModel has been likened to a conceptual state of the data as opposed to the real state of the data in the Model.

Controller: some references for MVVM also include a Controller layer

Book

Building Enterprise Applications with Windows Presentation Foundation and the MVVM Model View ViewModel Pattern by Raffaele Garofalo

Code

VB.Net Silverlight webcam example in MVVM

* ( EWD ) Edsger Wybe Dijkstra was one of the most influential members of computing science’s founding generation

His letters are published here http://www.cs.utexas.edu/users/EWD/ i can sure recomend you to read them especially EWD 1209 had a high impact on me  http://www.cs.utexas.edu/users/EWD/ewd12xx/EWD1209.PDF after reading remember that it was 1995 when he wrote this !

VB.NET Vs C# speed mythbuster

“A release build C# assembly is faster as a VB.Net assembly”  ( SIGH )

How can we bust this myth and explain the differences that people seem to have experienced ? , well there are some reassons why this is occuring and i would like to share them with you .

A debug build C# assembly is faster

VB.Net inserts more nop instructions in a debug build IL image this is the reasson why the VB IDE has verry advanced debug features in the Visual studio IDE and C#  not ( or at least not so advanced as the VB.Net IDE )

.method public static void  Main() cil managed
{
.entrypoint
.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )
// Code size       14 (0xe)
.maxstack  8
IL_0000:  nop
IL_0001:  ldstr   “Hello World”
IL_0006:  call    void [mscorlib]System.Console::WriteLine(string)
IL_000b:  nop
IL_000c:  nop
IL_000d:  ret
} // end of method Module1::Main

 The VB.Net Compiler  generates standard overflow checks for integer operations

Benchmarks results have been posted that do not accurately compare the performance of Visual Basic .NET to other languages , so switch the compiler option to the same default setting as the C# compiler is using and that is no checking at all , or write in C# yourself a checking struct

          VB.Net

Public Shared Sub RunLoop()
Dim I As Integer
Dim max As Integer = 500000000
Dim sum As Integer = 0

For I = 1 To max
sum += 1
Next

End Sub

              results in

.method public static void  RunLoop() cil managed
{
// Code size       27 (0x1b)
.maxstack  2
.locals init ([0] int32 I,
[1] int32 max,
[2] int32 sum,
[3] int32 _Vb_t_i4_0)
IL_0000:  ldc.i4     0x1dcd6500
IL_0005:  stloc.1
IL_0006:  ldc.i4.0
IL_0007:  stloc.2
IL_0008:  ldc.i4.1
IL_0009:  ldloc.1
IL_000a:  stloc.3
IL_000b:  stloc.0
IL_000c:  br.s       IL_0016
IL_000e:  ldloc.2
IL_000f:  ldc.i4.1
IL_0010:  add
IL_0011:  stloc.2
IL_0012:  ldloc.0
IL_0013:  ldc.i4.1
IL_0014:  add
IL_0015:  stloc.0
IL_0016:  ldloc.0
IL_0017:  ldloc.3
IL_0018:  ble.s      IL_000e
IL_001a:  ret
} // end of method Class1::RunLoop

            C#

public static void RunLoop()
{
int i;
int max = 500000000;
int sum = 0;
int loopLimit = max;
for (i = 1; i <= loopLimit; i++)
{
sum += 1;
}
}

          results in

.method private hidebysig static void  RunLoop() cil managed
{
// Code size       27 (0x1b)
.maxstack  2
.locals init ([0] int32 i,
[1] int32 max,
[2] int32 sum,
[3] int32 loopLimit)
IL_0000:  ldc.i4     0x1dcd6500
IL_0005:  stloc.1
IL_0006:  ldc.i4.0
IL_0007:  stloc.2
IL_0008:  ldloc.1
IL_0009:  stloc.3
IL_000a:  ldc.i4.1
IL_000b:  stloc.0
IL_000c:  br.s       IL_0016
IL_000e:  ldloc.2
IL_000f:  ldc.i4.1
IL_0010:  add
IL_0011:  stloc.2
IL_0012:  ldloc.0
IL_0013:  ldc.i4.1
IL_0014:  add
IL_0015:  stloc.0
IL_0016:  ldloc.0
IL_0017:  ldloc.3
IL_0018:  ble.s      IL_000e
IL_001a:  ret
} // end of method Class1::RunLoop

The only difference is the order of the instructions on lines IL_0008, IL_0009, and IL_000a

The Visual Basic .NET compiler will generate the IL instruction add.ovf for these addition operations. The add.ovf instruction includes an overflow check and throws an exception if the sum exceeds the capacity of the target data type  , the add.ovf instruction results in safer code however a Visual Basic coder could choose to dissable the overflow check at the compiler options tab , however standard it is turned on for a debug and a release build.

If we run the code i showed above there is no noticable speed difference although VB.Net actually has one extra integer on the stack however this is not measurable .

Unique Visual Basic Constructs

The Visual Basic language constructs are wrappers for methods and properties from the divers system classes and do not introduce significant performance penalties however in a comparisation , one should mimic the behavior of these shortcut constructs or use in both languages the same framework classes  .

      For instance

The VB language method Callbyname is not a one on one equivalant to objectPointer.GetType().GetProperty(“NameOfProperty”).SetValue(objectPointer, “value”, null) as some people seem to think , as Callbyname results in a few hundred  lines of  IL code where depending on the type of called object different checks and invocation paths are chosen  . So a C# coder should actually also write his code as defensive as the VB library does or in a comparisation the same framework methods should be used !

Conclusion

A release builded and equal style written .Net application is just as fast executing wether it was written in C# or VB.Net