Silverlight 5 has introduced a lot of new features and one of them is the ability to set binding on Style Setters. This great feature was heavily missing from the earlier Silverlight version. The functionality is pretty useful and is extensively used in WPF applications.

Implementing MVVM scenarios with controls inherited from ItemsControls is not an easy way and sometimes may require a lot of work.

Say binding IsSelected on C1TreeView or binding GroupName/HeaderBackground in C1Menu. There are lot of workarounds to these scenarios.

Setting binding in Style Setters is really helpful in these scenarios and it does reduces a lot of work.

Lets see this by an example. Below are the simple classes that we will be using for binding purposes:-

public class Parent
{
public string Name{get;set;}
public List<Child> Childs{get;set;}
public bool IsSelected { get; set; }
}

public class Child
{
public Child(string name)
{
this.Name=name;
}
public string Name{get;set;}
public bool IsSelected { get; set; }
}


Lets populate the collection in our ViewModel:-

public class MyViewModel
{
private List<Parent> _collections;
public MyViewModel()
{
_collections = new List<Parent>();
_collections.Add(new Parent() { Name = "P1", Childs = new List<Child>() { new Child("C11"){IsSelected=true} , new Child("C12"), new Child("C13") } });
_collections.Add(new Parent() { Name = "P2", IsSelected=true, Childs = new List<Child>() { new Child("C21"), new Child("C22"), new Child("C23") } });
_collections.Add(new Parent() { Name = "P3", Childs = new List<Child>() { new Child("C31"), new Child("C32"), new Child("C33") } });
}

public List<Parent> Collections
{
get
{
return _collections;
}
}
}


Next is important xaml that shows the entire binding stuff in xaml:-

<c1:C1TreeView ItemsSource="{Binding Collections}" Grid.Row="1">
<c1:C1TreeView.ItemTemplate>
<c1:C1HierarchicalDataTemplate ItemsSource="{Binding Childs}">
<TextBlock HorizontalAlignment="Stretch" Margin="2" Text="{Binding Name}"/>
</c1:C1HierarchicalDataTemplate>
</c1:C1TreeView.ItemTemplate>
<c1:C1TreeView.ItemContainerStyle>
<Style TargetType="c1:C1TreeViewItem">
<Setter    Property="IsSelected" Value="{Binding IsSelected}"/>
</Style>
</c1:C1TreeView.ItemContainerStyle>
</c1:C1TreeView>


As you can see from the above xaml code, we have used the ItemContainerStyle and bound the IsSelected property on the C1TreeViewItem with the IsSelected property exposed on our class. That was pretty simple. Isnt It?

With earlier versions, you may have to use some helper classes like SetterValueBindingHelper to achieve the same thing.

You can set similar type of styles to most of the controls inherited from ItemsControl like C1Menu, C1Accordion, C1Book etc.  while still obeying the rules of standard MVVM.

The things doesn't stop here. With this new feature, its pretty easy to bind the C1DataGrid's row /cell background/foreground/fontweight etc. all in xaml without manually setting the properties in code. See below xaml code which binds the IsAvailable property on the bound item to DataGridRowPresenters Background/Fontweight:-

<Style x:Key="myrowstyle" TargetType="c1:DataGridRowPresenter">
<Setter  Property="Background" Value="{Binding RelativeSource={RelativeSource Self}, Path=Row.DataItem.IsAvailable, Converter={StaticResource BackgroundConverter}}"/>
<Setter  Property="FontSize"  Value="{Binding RelativeSource={RelativeSource Self}, Path=Row.DataItem.IsAvailable, Converter={StaticResource FontweightConverter}}"/>
</Style>


Check attached sample for simple implementation.

Download Sample