Posted by: Zeeshan Amjad | March 1, 2014

Radio button in MVVM


Using the check box or any other control with MVVM is comparatively easy, because we usually bind one control with one property. But radio button is an interesting control, here we bind more than one control with one property.

When we are creating a radio button, we can defined different groups and all the radio button in one group work independent of other. And we usually bind one property to all radio button control in one group.

At our first step we bind all the radio button controls in one group to one variable, but the problem is how do we know which radio button is clicked. Let’s say we have a radio button group of direction. We have an enumerator for it.

Code Snippet
public enum Direction
{
    North,
    Easth,
    West,
    South
}

 

Which radio button is clicked we can achieve this in different ways. We can use the Converter and Converter Parameter to identify the radio button. We can even make that converter as a markup extension, so we even don’t have to create an object of it in XAML.

Here is a code of our simple enum to boolean convertor markup extension.

Code Snippet
[ValueConversion(typeof(bool), typeof(Enum))]
public class EnumToBoolExtension : MarkupExtension, IValueConverter
{
    #region IValueConverter
    
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return parameter.Equals(value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return ((bool) value) == true ? parameter : DependencyProperty.UnsetValue;
    }

    #endregion

    #region MarkupExtension

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }

    #endregion
}

 

And we can use this markup extension with radio button in this way.

Code Snippet
<RadioButton Grid.Row="0" GroupName="directionText" Margin="5" VerticalAlignment="Center" Content="North"
             IsChecked="{Binding Direction, Converter={local:EnumToBool}, ConverterParameter={x:Static local:Direction.North}}"/>
<RadioButton Grid.Row="1" GroupName="directionText" Margin="5" VerticalAlignment="Center" Content="East"
             IsChecked="{Binding Direction, Converter={local:EnumToBool}, ConverterParameter={x:Static local:Direction.Easth}}"/>
<RadioButton Grid.Row="2" GroupName="directionText" Margin="5" VerticalAlignment="Center" Content="West"
             IsChecked="{Binding Direction, Converter={local:EnumToBool}, ConverterParameter={x:Static local:Direction.West}}"/>
<RadioButton Grid.Row="3" GroupName="directionText" Margin="5" VerticalAlignment="Center" Content="South"
             IsChecked="{Binding Direction, Converter={local:EnumToBool}, ConverterParameter={x:Static local:Direction.South}}"/>

 

Rest of the things are very easy. We can create a enum Direction type property in our view Model to use radio button in MVVM.

Here is a complete C# code of the project.

Code Snippet
namespace WpfRadioButton
{
    using System;
    using System.ComponentModel;
    using System.Globalization;
    using System.Windows;
    using System.Windows.Data;
    using System.Windows.Markup;

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private ViewModel vm = new ViewModel();
        public MainWindow()
        {
            InitializeComponent();

            DataContext = vm;
        }
    }

    [ValueConversion(typeof(bool), typeof(Enum))]
    public class EnumToBoolExtension : MarkupExtension, IValueConverter
    {
        #region IValueConverter
        
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return parameter.Equals(value);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return ((bool) value) == true ? parameter : DependencyProperty.UnsetValue;
        }

        #endregion

        #region MarkupExtension

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return this;
        }

        #endregion
    }

    public enum Direction
    {
           North,
        Easth,
        West,
        South
    }

    public class ViewModel : INotifyPropertyChanged
    {
        public Direction direction;

        public Direction Direction
        {
            get
            {
                return this.direction;
            }

            set
            {
                this.direction = value;
                this.RaisePropertyChanged("Direction");
            }
        }

        #region NotifyPropertyChanged Methods

        public void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }
}

 

And here is complete XAML code of the project

Code Snippet
<Window x:Class="WpfRadioButton.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml&quot;
        xmlns:local="clr-namespace:WpfRadioButton"
        Title="RadioButton" Height="200" Width="300">
    <Grid DataContext="{Binding}">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <RadioButton Grid.Row="0" GroupName="directionText" Margin="5" VerticalAlignment="Center" Content="North"
                     IsChecked="{Binding Direction, Converter={local:EnumToBool}, ConverterParameter={x:Static local:Direction.North}}"/>
        <RadioButton Grid.Row="1" GroupName="directionText" Margin="5" VerticalAlignment="Center" Content="East"
                     IsChecked="{Binding Direction, Converter={local:EnumToBool}, ConverterParameter={x:Static local:Direction.Easth}}"/>
        <RadioButton Grid.Row="2" GroupName="directionText" Margin="5" VerticalAlignment="Center" Content="West"
                     IsChecked="{Binding Direction, Converter={local:EnumToBool}, ConverterParameter={x:Static local:Direction.West}}"/>
        <RadioButton Grid.Row="3" GroupName="directionText" Margin="5" VerticalAlignment="Center" Content="South"
                     IsChecked="{Binding Direction, Converter={local:EnumToBool}, ConverterParameter={x:Static local:Direction.South}}"/>
        <TextBlock Grid.Row="4" Margin="5" VerticalAlignment="Center" Text="{Binding Direction}"/>
    </Grid>
</Window>

 

This is an output of the program.

WpfRadioButtonMVVM

Advertisements

Responses

  1. Thanks a lot. My code was missing the DependencyProperty.UnsetValue return. Spent a few hours & solved it after reaching here.

    • I am glad it helped. Thanks for visiting.

      • Good I would translate in VB.NET but I have no succes. Everyone write this example in VBNET? Thanks

      • I think converting in VB.Net shouldn’t be very difficult. I am sure there are already tons of article on the net that does it. If I will have a time, i will write VB.Net version of it.

  2. Can you do it without writting code in window.xaml.cs file??
    like making a separate cs file?

    • There is no code behind in this project. For simplicity I wrote all code in one file, but that is not necessary. Thanks for visiting my blog.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: