views:

1531

answers:

1

Hi,

Does anyone have a successful workaround for changing a style in silverlight based on a property of the underlying data object, in that when the value changes so does the style. I used WPF briefly and it obviously has the DataTrigger which seems to cover this but it is missing in Silverlight.

I found this: http://blois.us/blog/2009/04/datatrigger-bindings-on-non.html

But it doesn't seem to apply to styling..

Thanks for your time

+6  A: 

Silverlight doesn't contain a DataTemplateSelector, which is used to select a data template based on the data-bound element and the data object. But, it isn't hard to build your own.

Start with a class that inherits from System.Windows.Controls.ContentControl. This class has a property for a data template and a property for content, which you can use to bind to. Create an override on the OnContentChanged method like this

protected override void OnContentChanged(object oldContent, object newContent) 
{
}

I prefer to place Templates in a separate dictionary, just in case I need to share them between projects. In this method set the template of this control to a template picked from the dictionary. Something like:

Switch(DataStatus){
  case 0: ContentTemplate = LoadFromDictionary(
                                "DataTemplateDemo;component/DataTemplates.xaml",
                                "Status0Template");
          break;
  case 1: ContentTemplate = LoadFromDictionary(
                                "DataTemplateDemo;component/DataTemplates.xaml", 
                                "Status1Template");
          break;
   //etc      
}

in this case the should be a dictionary name DataTemplates.xaml with a couple of data templates.

In your xaml file, use the template selector class as the template of the list:

 <ListBox x:Name="AnInterrestingList">
    <ListBox.ItemTemplate>
    <DataTemplate>
        <DataTemplateDemo:DateTemplateSelector Content="{Binding}"/>
    </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

I use this helper method like below to retreive templates from dictionaries:

public static DataTemplate LoadFromDictionary(string dictionary,
                                              string template)
{
    var doc = XDocument.Load(dictionary);
    var dict = (ResourceDictionary)XamlReader
                     .Load(doc.ToString(SaveOptions.None));
    return dict[template] as DataTemplate;
}

Update

In the meantime I've written a blogpost with sample code about this subject. It's available on my blog.

Sorskoot
Been looking for something like this!, Google + You = Thanks!
Chris Schroeder