BLOG ARTICLE ViewModel | 1 ARTICLE FOUND

  1. 2009.09.14 WPF RadioButtons in MVVM... (3)


If you try to use RadioButtons as usual in MVVM, it will not work as you expect.
For example, here is a very simple UI using two RadioButtons.

A very simple UI using two RadioButtons.


My first attempt is to use this View:
...
<GroupBox Header="I love">
    <StackPanel>
        <RadioButton IsChecked="{Binding IsPeaceLover}">Peace</RadioButton>
        <RadioButton>Earth</RadioButton>
    </StackPanel>
</GroupBox>
...
and this ViewModel:
class UserViewModel : ViewModelBase
{
    bool isPeaceLover = true;

    public bool IsPeaceLover
    {
        get { return this.isPeaceLover; }
        set
        {
            if (this.isPeaceLover == value)
                return;

            this.isPeaceLover = value;
            OnPropertyChanged("IsPeaceLover");
        }
    }
    ...
}
But as you may know, it doesn't work. There are many solutions to avoid this problem.
Anyway, I've created a new pattern that is more appropriate to MVVM (not using Code-Behind).
Try this View:
...
<GroupBox Header="I love">
    <StackPanel>
        <RadioButton IsChecked="{Binding IsPeaceLover}">Peace</RadioButton>
        <RadioButton IsChecked="{Binding IsEarthLover}">Earth</RadioButton>
    </StackPanel>
</GroupBox>
...
and this ViewModel:
class UserViewModel : ViewModelBase
{
    bool isPeaceLover = true;

    public bool IsPeaceLover
    {
        get { return this.isPeaceLover; }
        set
        {
            if (this.isPeaceLover == value)
                return;

            this.isPeaceLover = value;
            OnPropertyChanged("IsPeaceLover", "IsEarthLover");
        }
    }

    public bool IsEarthLover
    {
        get { return !IsPeaceLover; }
        set { IsPeaceLover = !value; }
    }
    ...
}
If you have more options user can choose, you can extend the pattern like this:
public enum Priority
{
    Low,
    Middle,
    High,
}

class JobViewModel : ViewModelBase
{
    Priority priority = Priority.Low;

    public Priority Priority
    {
        get { return this.priority; }
        set
        {
            if (this.priority == value)
                return;

            this.priority = value;
            OnPropertyChanged("Priority"
                     , "IsLowPriority", "IsMiddlePriority", "IsHighPriority");
        }
    }

    public bool IsLowPriority
    {
        get { return Priority == Priority.Low; }
        set { Priority = value ? Priority.Low : Priority; }
    }

    public bool IsMiddlePriority
    {
        get { return Priority == Priority.Middle; }
        set { Priority = value ? Priority.Middle : Priority; }
    }

    public bool IsHighPriority
    {
        get { return Priority == Priority.High; }
        set { Priority = value ? Priority.High : Priority; }
    }
}
...
<GroupBox Header="Priority">
    <StackPanel>
        <RadioButton IsChecked="{Binding IsLowPriority}">Low</RadioButton>
        <RadioButton IsChecked="{Binding IsMiddlePriority}">Middle</RadioButton>
        <RadioButton IsChecked="{Binding IsHighPriority}">High</RadioButton>
    </StackPanel>
</GroupBox>
...


YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST
  1. bob 2011.08.16 02:18  댓글주소  수정/삭제  댓글쓰기

    ...srlsy? it works if you have two choice but 99% of use cases you have more than two choices and then your solution is useless. Worst than that, if you app evolve (new need) you have to redo it totally and choose another solution. Sorry but a good developer should consider future features when he makes choices like that

    • Favicon of https://blog.ryeol.com BlogIcon ryeol 2011.08.16 02:47 신고  댓글주소  수정/삭제

      I use this pattern for a small option set.
      If you do not meet this condition, you should consider collection related solutions such as CollectionView and ComboBox.

      Thanks for your comment.