views:

2008

answers:

3
+12  Q: 

MVVM radiobuttons

Someone please help. I have an interesting issue. I am trying to implement an MVVM app and I want to bind to radiobuttons in my view.

Here's my view:

<StackPanel Orientation="Horizontal" Grid.ColumnSpan="2"  >
    <RadioButton GroupName="1" IsChecked="{Binding Path=NoteGeneral, Mode=TwoWay}">General</RadioButton>
    <RadioButton GroupName="1" IsChecked="{Binding Path=NoteContact, Mode=TwoWay}" >Contact</RadioButton>
    <RadioButton GroupName="1" IsChecked="{Binding Path=NoteAddress, Mode=TwoWay}" >Address</RadioButton>
    <RadioButton GroupName="1" IsChecked="{Binding Path=NotePhone, Mode=TwoWay}" >Phone</RadioButton>
</StackPanel>

Here's my ViewModel:

    bool _NoteGeneral;
    public bool NoteGeneral
    {
        get { return _NoteGeneral; }
        set
        {
            _NoteGeneral = value;
            OnPropertyChanged("NoteGeneral");
        }
    }

    bool _NoteContact;
    public bool NoteContact
    {
        get { return _NoteContact; }
        set
        {
            _NoteContact = value;
            OnPropertyChanged("NoteContact");
        }
    }

    bool _NoteAddress;
    public bool NoteAddress
    {
        get { return _NoteAddress; }
        set
        {
            _NoteAddress = value;
            OnPropertyChanged("NoteAddress");
        }
    }

    bool _NotePhone;
    public bool NotePhone
    {
        get { return _NotePhone; }
        set
        {
            _NotePhone = value;
            OnPropertyChanged("NotePhone");
        }
    }

The problem is this, when I click the different radiobuttons the property setter only gets called the first time(when i run thru debugging). e.g. When I click NoteGeneral, NoteContact, then NoteGeneral again only the first two clicks update my viewmodel. I think I might have something wrong with my binding, or maybe I'm approaching this the completely wrong way.

Can anyone help?

How should I implement radiobutton selections in my viewmodel?

+6  A: 

Take a look here.

I haven't implemented the solution provided but it makes sense. The underlying framework control breaks you bindings when a click is performed. The solution is to override the method that does this and just rely on the bindings.

Jab
wow, thanks, i couldn't google it for the life of me. :)
Jose
Just ran into the same situation, this helped a ton.Thanks!
stevosaurus
See also http://stackoverflow.com/questions/2284752/mvvm-binding-radio-buttons-to-a-view-model for some other solutions, particularly a rather simple solution involving a list box.
David Veeneman
A: 

I've written a simple tip for this problem on my blog.

In this case, you should write the View and the ViewModel as the following:

<StackPanel Orientation="Horizontal" Grid.ColumnSpan="2">
    <RadioButton IsChecked="{Binding IsGeneralNote}">General</RadioButton>
    <RadioButton IsChecked="{Binding IsContactNote}">Contact</RadioButton>
    <RadioButton IsChecked="{Binding IsAddressNote}">Address</RadioButton>
    <RadioButton IsChecked="{Binding IsPhoneNote}">Phone</RadioButton>
</StackPanel>


public enum Note
{
    General,
    Contact,
    Address,
    Phone,
}

...

    Note note = Note.General;

    public Note Note
    {
        get { return this.note; }
        set
        {
            if (this.note == value)
                return;

            this.note = value;
            OnPropertyChanged("Note");
            OnPropertyChanged("IsGeneralNote");
            OnPropertyChanged("IsContactNote");
            OnPropertyChanged("IsAddressNote");
            OnPropertyChanged("IsPhoneNote");
        }
    }

    public bool IsGeneralNote
    {
        get { return Note == Note.General; }
        set { Note = value ? Note.General : Note; }
    }

    public bool IsContactNote
    {
        get { return Note == Note.Contact; }
        set { Note = value ? Note.Contact : Note; }
    }

    public bool IsAddressNote
    {
        get { return Note == Note.Address; }
        set { Note = value ? Note.Address : Note; }
    }

    public bool IsPhoneNote
    {
        get { return Note == Note.Phone; }
        set { Note = value ? Note.Phone : Note; }
    }
...
Ryeol
This solution doesn't address the problem of RadioButton bindings getting clobbered when the button is selected, does it?
David Veeneman
I've written samples on my blog. You can try it at http://www.ryeol.com/27
Ryeol
+3  A: 

Jaime Rodriguez, who works at Microsoft on WPF, publishes an unabridged Q&A on WPF, and the latest issue has a post on RadioButtons and MVVM !

The post is at http://blogs.msdn.com/jaimer/archive/2009/09/22/wpf-discussion-090922.aspx, and you want to look at the last item in that post. I tested the solution and it works to my satisfaction.

Quoted for convenience:

I've worked around this issue in .NET 3.5 SP1. Here's how I data bind a group of radio buttons to an enum-valued property:

<StackPanel>
    <RadioButton Content="New folder"
        IsChecked="{Binding Path=PublishTarget,
                    Converter={StaticResource equalityConverter},
                    ConverterParameter={x:Static local:PublishTarget.NewServerFolder}, Mode=TwoWay}"
        GroupName="1" />

    <RadioButton Content="Existing folder"
        IsChecked="{Binding Path=PublishTarget,
                    Converter={StaticResource equalityConverter},
                    ConverterParameter={x:Static local:PublishTarget.ExistingServerFolder},
                    Mode=TwoWay}"
        GroupName="2" />

    <RadioButton Content="Local folder"
        IsChecked="{Binding Path=PublishTarget,
                    Converter={StaticResource equalityConverter},
                    ConverterParameter={x:Static local:PublishTarget.LocalFolder},
                    Mode=TwoWay}"
        GroupName="3" />
</StackPanel>

Setting each radio button's GroupName to a unique value prevents the bindings from getting clobbered when the user clicks on a radio button. Here I'm relying on the data source to implement INotifyPropertyChanged, which will tell the other radio buttons to update. A similar approach should work for radio buttons in an ItemsControl.

Thomas Dufour