Tuesday, July 27, 2010

DataForm + Combobox == Silly Bugs (combobox in dataFormToolkit:DataField)

UPDATE: So, this worked for SOME of the problems... not All.... Mosy on over to John's blog to see updates that he has for this issue. I believe he has fixed it.


Well... I haven't posted in a really long time... but this problem / workaround was worth it. My amazingly cool and awesome collegue John, had a most annoying problem. He was trying to bind a combobox to an itemsource then take the value of that itemsource and put it into a RIA Domain data source. Sounds easy right? well... not so when you're using the Silverlight 4 Toolkit DataForm / DataGrid.

Each time the form reloads (by adding, removing items from the collection) the bindings are reset, and not nicely... Long story short we found it impossible to get the combo box to work correctly using anything in XAML. For some reason "they" haven't made it easy in Silverlight.

To work around this issue the easiest thing I could come up with turns out to be pretty neat. On the Datafield that held the combo box, there is a Loaded event, so I thunk (yes, thunk; We were very frustrated...) why not just add a new combobox each time it loads so we KNOW that the bindings are correct.

Here is what we did:

Added an empty datafield to the grid in the dataform:

dataFormToolkit:DataField Grid.Row="5" Grid.Column="0" Loaded="ComboBoxField_Loaded" Label="Period Type" LabelPosition="Auto"

Note the lovely RED event handler.

in this hanlder we define the contents of this DataField:





Private Sub ComboBoxField_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)



Dim comboBoxField As DataField = sender 'Get the dataField that sent us here


Dim BindingForItems As New Binding With {.Source = ItemListDomainDataSource,
.Path = New PropertyPath("Data")}



'No need to set Source as it will pick up from the form


Dim BindingForValue As New Binding With {.Path = New PropertyPath("ItemValue"),
.Mode = BindingMode.TwoWay}



Dim combobox As ComboBox = New ComboBox 'Make a new combobox
combobox.DisplayMemberPath = "Name" 'Set Paths FIRST, yes, they have to be done first
combobox.SelectedValuePath = "PeriodType"
combobox.SetBinding(combobox.ItemsSourceProperty, BindingForItems)
combobox.SetBinding(combobox.SelectedValueProperty, BindingForValue)

'add styling wireups if not using default styling

comboBoxField.Content = combobox 'Push the new combobox back to the datafield



End Sub




So, load the data field, add the combobox, with its bindings already set. Now, for all those that are super concerned, like my friend John, about performance etc, you should go look at his blog, 'cause i am pretty sure he will take this and turn it into some shared resource.... :)




Add to Google