MVVM radiobuttons

时间:2009-05-19 14:49:22

标签: data-binding mvvm

有人请帮忙。我有一个有趣的问题。我正在尝试实现一个MVVM应用程序,我想在我的视图中绑定到radiobuttons。

以下是我的观点:

<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>

这是我的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");
        }
    }

问题在于,当我单击不同的单选按钮时,属性设置器仅在第一次调用时(当我通过调试运行时)。例如当我单击NoteGeneral,NoteContact,然后NoteGeneral再次只有前两次点击更新我的viewmodel。我想我的绑定可能有问题,或者我正在以完全错误的方式接近这个问题。

有人可以帮忙吗?

我应该如何在viewmodel中实现radiobutton选择?

.NET 4及更高版本

当.NET 4发布时,Microsoft解决了RadioButton绑定的这个问题。 RadioButtons的绑定现在可以正常工作,无需下面列出的任何解决方法。

4 个答案:

答案 0 :(得分:18)

看看here

我没有实现所提供的解决方案,但这是有道理的。执行单击时,底层框架控件会破坏绑定。解决方案是覆盖执行此操作的方法,并且只依赖于绑定。

答案 1 :(得分:15)

Jaime Rodriguez,曾在微软的WPF工作,在WPF上发布了一个完整的Q&amp; A,最新一期在RadioButtons和MVVM上有一篇文章!

帖子位于http://blogs.msdn.com/jaimer/archive/2009/09/22/wpf-discussion-090922.aspx,您想查看该帖子中的最后一项。我测试了解决方案并且令我满意。

引用方便:

  

我在.NET 3.5 SP1中解决了这个问题。以下是我将一组单选按钮绑定到枚举值属性的方法:

<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>
  

将每个单选按钮的GroupName设置为唯一值可防止绑定在用户单击单选按钮时被破坏。在这里,我依靠数据源来实现INotifyPropertyChanged,它将告诉其他单选按钮进行更新。类似的方法应该适用于ItemsControl中的单选按钮。

答案 2 :(得分:8)

我已经在我的博客上为此问题撰写了a simple tip

在这种情况下,您应该按如下方式编写View和ViewModel:

<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; }
    }
...

答案 3 :(得分:0)

你必须设置UpdateSourceTrigger =&#34; PropertyChanged&#34;在XAML绑定像

 <StackPanel Grid.Column="1" Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center">
            <RadioButton Name="rdbTimeFormat12" GroupName="TimeFormat" Content="12 Hrs" IsChecked="{Binding Radio1IsCheck,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
            <RadioButton Name="rdbTimeFormat24" GroupName="TimeFormat" Margin="40,0,0,0" Content="24 Hrs" IsChecked="{Binding Radio2IsCheck,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
        </StackPanel>