Binding in Csla and Silverlight

Binding in Csla and Silverlight

Old forum URL: forums.lhotka.net/forums/t/7532.aspx


CyclingFoodmanPA posted on Friday, August 28, 2009

First of all, the Csla/Silverlight Videos Rock.  If you are developing a Csla application with Silverlight and have not bought the videos BUY THEM NOW!  I have gotten lots of things working, including compression in no time after going watching the videos.  I had expected some problems (hey, Murphy is everywhere and he always messes with my projects) even after going through the videos but things are going smoothly.  I do have one question Rocky or whoever else answers this.  There is a layout grid as follows:

<Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource data}, Path=Data}">
and the actual data grid is as follows:
<swcd:DataGrid x:Name="LineItemsDataGrid" AutoGenerateColumns="False"Margin="5" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Visible" ItemsSource="{Binding}">

Why was the binding set up this way?  I tried the following and it works also:
<Grid x:Name="LayoutRoot">
and the data grid is as follows:
<controls:DataGrid x:Name="PaddsDataGridAutoGenerateColumns="False" AlternatingRowBackground="LightGreen" HorizontalAlignment="Left" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Visible" ItemsSource="{Binding Source={StaticResource Padds}, Path=Data}" Margin="5Width="Auto">

They both work, but what was your reason for doing it this way?  Once I got things working, I started changing things to see what would happen and it worked both ways.

Thanks,

CyclingFoodmanPA

SonOfPirate replied on Sunday, August 30, 2009

Your question goes to the "art" of UI development.  You are correct that both scenarios work as expected and are valid approaches.  I can't speak for Rocky, but typically you'll want to set the DataContext at the LayoutRoot level so the data source is available to all controls in the page/user control.  When there is only one control bound to the source, this can seem unnecessary but imagine a page where you have multiple controls bound to the same source, such as a master/details view.  In this case, you want to bind at a level higher than both the master (presumably standard fields in a grid layout) and the details (possibly a data grid).

I said this is more art than science because you could chose to always do it the same way regardless of the actual layout or alter your approach per implemenation so you only set the data source at the highest level it is needed.  This is personal preference.

That said, I understand there are performance implications when setting the DataContext at the root level because of the way Silverlight "bubbles" the object down the control tree.  I don't know the details myself but have read that doing so with heavily nested controls can degrade performance.  So, take that for what it's worth.

Hope that helps...

 

RockfordLhotka replied on Monday, August 31, 2009

Yeah, the whole XAML thing is new enough that I don't think there's one "best practice" out there.

And maybe there won't be.

If you are hand-coding the XAML it typically makes most sense to set the datacontext at a container level so you can create sub-regions on the form and manage the datacontext values easily.

If you are using tool-based (Blend or code-gen) it might make more sense to explicitly set each control (though I rather doubt it - as it makes dynamic changes harder).

And then there's the whole MVVM pattern thing - which says you should bind your UI to one or more ViewModel objects, which expose the underlying Model (business object) as a property. This seems to be where things are going - certainly it is the trendy idea at the moment.

You can think of CslaDataProvider as a generic ViewModel object - in which case you'd want to set your overall datacontext to the data provider, and set your individual control binding paths to Data.Property - so Data.Name, Data.City, Data.State, etc.

The advantage of this, is that you can (in CSLA 3.8) use InvokeMethod or the new Invoke trigger action to execute the Save/Cancel/etc methods on the data provider based on the ambient datacontext, because the ambient datacontext is the data provider.

The new (in 3.8) ViewModel<T> is an alternative to the data provider, and arguably makes this even a little easier.

CyclingFoodmanPA replied on Tuesday, September 01, 2009

Thanks for the response Rocky.  I am doing hand-coding now and hope to get a tool to do it, but wanted the experience of hand-coding it first to understand what is going on.  Geeze, now I am getting excited about 3.8 to see what it does.  My brain is going to go in overload!

CyclingFoodmanPA

 

CyclingFoodmanPA replied on Tuesday, September 01, 2009

Thanks SonOfPirate, you made some good points.

CyclingFoodmanPA

Copyright (c) Marimer LLC