drafting behaviors

Posted by Karim on July 27, 2009

I finally had a chance to explore Expression Blend’s Interactivity SDK a bit and put together a simple HelloWorld app using it with Blend 3.

Screenshot

At the center is a rough custom Behavior that is able to share the visual state of controls that are bound to the same data object. Once the behavior was functional, I simply needed to add the behavior to two Buttons, bind the buttons to the same data, and wire an event to trigger the state change.

<Button MouseEnter="enterHandler" MouseLeave="leaveHandler">
  <i:Interaction.Behaviors>
    <local:SharedVisualStateBehavior Source="{Binding}" />
  </i:Interaction.Behaviors>
</Button>

private void enterHandler(object sender, MouseEventArgs e)
{
  SharedVisualStateBehavior.GoToSharedState(
    (Control)sender, "MouseOver");
}
private void leaveHandler(object sender, MouseEventArgs e)
{
  SharedVisualStateBehavior.GoToSharedState(
    (Control)sender, "Normal");
}

Because of the need to call a static method to actually make use of it, meaning it’s not selfcontained, it doesn’t really qualify as a Behavior.  The ideal SharedVSM would be able to take input in the form of VisualState parameters and possibly a trigger, in order to notify the shared controls of state changes.  It’s a work in progress.

Thanks to Kuler for the theme, Josh Smith for ObserveableObject from MVVM Foundation, and Pete Blois for BindingListener from Expression Samples.

radiobuttons in a datatemplate in silverlight 1

Posted by Karim on March 08, 2009

I was recently asked by a customer, “Why doesn’t RadioButton.GroupName work when a single RadioButton is put in a DataTemplate within an ItemsControl?” I had no answer. When I tried it out myself, lo and behold, two checked RadioButtons were staring back at me. A quick search told me that others have encountered this issue, and none had found a solution based in markup.

To illustrate the mechanics of Attached Behaviors, a topic that I had been reviewing with my customer, I decided to implement a working RadioButtonGroup as one. Simply use the attached property in place of RadioButton.GroupName, and the behavior takes care of the rest.

<ItemsControl ItemsSource="{Binding DataCollection}">
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <StackPanel Orientation="Horizontal" />
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <RadioButton Content="{Binding Name}"
                   b:RadioButtonGroup.Name="1"/>
    </DataTemplate>
  </ItemsControl.ItemTemplate>
</ItemsControl>

One interesting detail about my implementation: It can be used with ToggleButtons to achieve RadioButton-like behavior.

The solution source is available here. Feedback welcome.

Side note: Using reflector, I noticed that although RadioButton has all the necessary plumbing to group arbitrary radio buttons (and that code is remarkably similar to how a standard attachedbehavior is implemented), it relied on the “Logical Tree”, FrameworkElement.Parent, to scope group names to a common root node. One side effect of using ItemsControl is that the ContentPresenters used to show an item’s DataTemplate are severed from their parents. Parent is always null. This attached behavior doesn’t use that, and in fact it does not scope the group Names at all, so be sure to choose unique names.

Enjoy!