# Thursday, January 22, 2009
Yesterday I posted a bit about a dynamic survey in Silverlight, and today I wanted to start delving into a few details.  First of all, databinding to a user control…

I wanted my datagrid to show a series of radio buttons representing a “rating” from 1-5, where that rating corresponds to an enum value in C# and an integer in SQL. 

CropperCapture[4]

For databinding to work the way I’d want, I need to bind the one value in the source to the set of radio buttons in the target.  The easiest way I could think of (and there may be a better way I haven’t thought of) was to make the radio buttons into a user control, and expose a single value.  In the XAML for the datagrid, it looks like

<data:DataGridTemplateColumn.CellTemplate>

    <DataTemplate>

        <t:Rating UserRating="{Binding Path=Answer, Mode=TwoWay}" />

    </DataTemplate>

</data:DataGridTemplateColumn.CellTemplate>

The CellTemplate contains just the user control, and binds its UserRating property to the Answer property in the source.

The XAML for the UserControl is simple

<UserControl x:Class="Evaluation.Rating"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >

    <StackPanel Orientation="Horizontal">

        <RadioButton Content="Excellent (5)" x:Name="excellent" Checked="excellent_Checked"/>

        <RadioButton Content="Good" x:Name="good" Checked="good_Checked"/>

        <RadioButton Content="Neutral" x:Name="neutral" Checked="neutral_Checked"/>

        <RadioButton Content="Adequate" x:Name="adequate" Checked="adequate_Checked"/>

        <RadioButton Content="Poor (1)" x:Name="poor" Checked="poor_Checked"/>

    </StackPanel>

</UserControl>

In order to get two-way databinding notifications to work properly both ways, the UserRating property of the control is implemented as a DependencyProperty…

public ScaledAnswer UserRating

{

    get { return (ScaledAnswer)GetValue(UserRatingProperty); }

    set { SetValue(UserRatingProperty, value); }

}

 

// Using a DependencyProperty as the backing store for UserRating.  This enables animation, styling, binding, etc...

public static readonly DependencyProperty UserRatingProperty =

    DependencyProperty.Register("UserRating", typeof(ScaledAnswer), typeof(Rating), new PropertyMetadata(new PropertyChangedCallback(RatingChangedCallback)));

Note the callback registered for the PropertyChanged event of the dependency property.  If databinding changes the value of the dependency property, we still need to update the UI to check the right radio button.

private static void RatingChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)

{

    Rating r = d as Rating;

    r.updateUi((ScaledAnswer)e.NewValue);

 

}

 

private void updateUi(ScaledAnswer rating)

{

    switch (rating)

    {

        case ScaledAnswer.Excellent:

            excellent.IsChecked = true;

            break;

        case ScaledAnswer.Good:

            good.IsChecked = true;

            break;

        case ScaledAnswer.Neutral:

            neutral.IsChecked = true;

            break;

        case ScaledAnswer.Adequate:

            adequate.IsChecked = true;

            break;

        case ScaledAnswer.Poor:

            poor.IsChecked = true;

            break;

    }

}

Finally, the user control handles all the radio button “Checked” events and sets the value of the DependencyProperty to the correct value.

The UserControl provided a fairly smooth way of handling the databinding without having to implement a custom control, and could be reused in other contexts.  There’s probably a way to make it a bit more dynamic to handle more radio buttons, etc. but this worked for my particular case.

Thursday, January 22, 2009 12:54:28 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
Comments are closed.