MVVM单选button
有人请帮忙。 我有一个有趣的问题。 我想实现一个MVVM应用程序,我想绑定到我认为的单选button。
这是我的看法:
<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"); } }
问题是这样的,当我点击不同的单选button时,属性设置器第一次被调用(当我运行通过debugging)。 例如,当我点击NoteGeneral,NoteContact,然后NoteGeneral再次只有前两个点击更新我的viewmodel。 我想我的装订可能有问题,或者我正在接近完全错误的方式。
谁能帮忙?
我应该如何在我的viewmodel中实现单选buttonselect?
.NET 4及更高版本
.NET 4发布时,Microsoft解决了与RadioButton绑定的这个问题。 RadioButtons的绑定现在可以像你期望的那样工作,而不需要下面列出的任何解决方法。
看看这里 。
我没有实施提供的解决scheme,但它是有道理的。 当执行点击操作时,底层框架控件会打断您的绑定。 解决scheme是重写这个方法,只依赖于绑定。
在微软工作的WPF的Jaime Rodriguez发表了一篇关于WPF的完整问答,最近的一期在RadioButtons和MVVM上发表了一篇文章!
这篇文章是在http://blogs.msdn.com/jaimer/archive/2009/09/22/wpf-discussion-090922.aspx ,你想看看这个职位的最后一个项目。 我testing了解决scheme,它的工作令我满意。
引用方便:
我在.NET 3.5 SP1中解决了这个问题。 以下是我如何将一组单选button绑定到枚举值的属性:
<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>
将每个单选button的GroupName设置为一个唯一的值可防止绑定在用户单击单选button时被破坏。 在这里,我依靠数据源来实现INotifyPropertyChanged,它将告诉其他单选button更新。 一个类似的方法应该为ItemsControl中的单选button工作。
我在博客上为这个问题写了一个简单的提示 。
在这种情况下,您应该按如下方式编写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; } } ...
你必须在XAML绑定中设置UpdateSourceTrigger =“PropertyChanged”
<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>