RadMenu for Silverlight supports simple checkable items, but still does not support radio button items. This feature is scheduled for development and most probably will come with Q3 2009, but until then you have to code it by yourself. Fortunately, this is relatively easy with a proper ViewModel, that contains the radio-button logic:

checkablemenuitems

The CommandItem class contains the properties and the logic for a RadMenuItem. It implements INotifyPropertyChanged and its most important property is IsChecked:

public bool IsChecked
{
    get
    {
        return this.isChecked;
    }
    set
    {
        if (this.isChecked != value)
        {
            this.isChecked = value;
            this.OnPropertyChanged("IsChecked");

            if (!string.IsNullOrEmpty(this.GroupName))
            {
                if (this.IsChecked)
                {
                    this.UncheckOtherItemsInGroup();
                }
                else
                {
                    this.IsChecked = true;
                }
            }
        }
    }
}

The GroupName property holds the name of the radio-button group that the current RadMenuItem belongs to. The setter of IsChecked will uncheck all other items that belong to the same group, or will check itself if it was unchecked. The self-check is made because we don’t want the user to be able to click on a checked radio-button and to uncheck it. If the item does not belong to a group, e.g. it is not a radio-button, it will behave as a regular check-box, that is toggled on each click.

The UncheckOtherItemsInGroup() searches for items with the same GroupName within the Parent’s Items collection, and unchecks them:

private void UncheckOtherItemsInGroup()
{
    var groupItems = this.Parent.Items.Where((item) => item.GroupName == this.GroupName);
    foreach (CommandItem item in groupItems)
    {
        if (item != this)
        {
            item.isChecked = false;
            item.OnPropertyChanged("IsChecked");
        }
    }
}

 

Note that I set the isChecked member and raise PropertyChanged, instead of setting the IsChecked property. This is because I don’t want to trigger the unchecking logic from the IsChecked setter again.

The menu is data-bound to the ViewModel with a HierarchicalDataTemplate and ContainerBindings:

<telerik:ContainerBindingCollection x:Key="ContainerBindings"> <telerik:ContainerBinding PropertyName="IsSeparator" Binding="{Binding IsSeparator}" /> <telerik:ContainerBinding PropertyName="IsChecked" Binding="{Binding IsChecked, Mode=TwoWay}" /> <telerik:ContainerBinding PropertyName="StaysOpenOnClick" Binding="{Binding IsCheckable}" /> <telerik:ContainerBinding PropertyName="IsCheckable" Binding="{Binding IsCheckable}" /> </telerik:ContainerBindingCollection> <telerik:HierarchicalDataTemplate x:Key="ItemTemplate" ItemsSource="{Binding Items}" telerik:ContainerBinding.ContainerBindings="{StaticResource ContainerBindings}"> <TextBlock Text="{Binding Text}" /> </telerik:HierarchicalDataTemplate>
...
<telerikNavigation:RadMenu VerticalAlignment="Top" DataContext="{StaticResource MenuViewModel}" ItemsSource="{Binding Items}" ItemTemplate="{StaticResource ItemTemplate}" />

The ContainerBindings are a temporary workaround for the inability of the Silverlight 2 styles to set Bindings. In two words, when a Telerik ItemsControl finds the ContainerBindings attached proeprty it will automatically set the specified bindings on the specified properties. In this case, the IsSeparator property of RadMenuItem will be bound to the IsSeparator property of CommandItem, etc.

Last, but not least, is the ViewModel. I will show the XAML declaration, but if you want to, you may initialize it from a web service or the code-behind (as in the attached application):

<local:MenuViewModel x:Key="MenuViewModel"> <local:CommandItem Text="File"> <local:CommandItem Text="Exit" /> </local:CommandItem> <local:CommandItem Text="Options"> <local:CommandItem Text="CheckBox 1" IsCheckable="True" /> <local:CommandItem Text="CheckBox 2" IsCheckable="True" /> <local:CommandItem Text="CheckBox 3" IsCheckable="True" /> <local:CommandItem IsSeparator="True" /> <local:CommandItem Text="RadioButton 1.1" GroupName="1" /> <local:CommandItem Text="RadioButton 1.2" GroupName="1" /> <local:CommandItem Text="RadioButton 1.3" GroupName="1" /> <local:CommandItem IsSeparator="True" /> <local:CommandItem Text="RadioButton 2.1" GroupName="2" /> <local:CommandItem Text="RadioButton 2.2" GroupName="2" /> <local:CommandItem Text="RadioButton 2.3" GroupName="2" /> <local:CommandItem IsSeparator="True" /> <local:CommandItem Text="RadioButton 3.1" GroupName="3" /> <local:CommandItem Text="RadioButton 3.2" GroupName="3" /> <local:CommandItem Text="RadioButton 3.3" GroupName="3" /> </local:CommandItem> </local:MenuViewModel>

 

Here is the source code:


Related Posts

Comments

Comments are disabled in preview mode.