如果你想使用 RadioButtons,你只需要做一些小的调整来解决 RadioButton 的默认行为。
您需要解决的第一个问题是 RadioButtons 基于其公共直接父容器的自动分组。由于您不喜欢“GroupName”破解,您的另一个选择是将每个 RadioButton 放入其自己的 Grid 或其他容器中。这将使每个按钮成为其自己组的成员,并强制它们根据其 IsChecked 绑定行事。
<StackPanel Orientation="Horizontal">
<Grid>
<RadioButton IsChecked="{Binding Path=CurrentMode, Converter={StaticResource enumBooleanConverter}, ConverterParameter=Idle}">Idle</RadioButton>
</Grid>
<Grid>
<RadioButton IsChecked="{Binding Path=CurrentMode, Converter={StaticResource enumBooleanConverter}, ConverterParameter=Active}">Active</RadioButton>
</Grid>
<Grid>
<RadioButton IsChecked="{Binding Path=CurrentMode, Converter={StaticResource enumBooleanConverter}, ConverterParameter=Disabled}">Disabled</RadioButton>
</Grid>
<Grid>
<RadioButton IsChecked="{Binding Path=CurrentMode, Converter={StaticResource enumBooleanConverter}, ConverterParameter=Running}">Running</RadioButton>
</Grid>
</StackPanel>
这使我想到了下一个解决方法,即确保单击的按钮在单击它后不会保持其 Checked 状态,这是触发 set 调用所需的,因为您绑定了 IsChecked 属性。您将需要发送一个额外的 NotifyPropertyChanged,但它必须被推入 Dispatch 线程的队列,以便按钮接收通知并更新其可视 IsChecked 绑定。将此添加到您的 ViewModel 类中,这可能会替换您现有的 NotifyPropertyChanged 实现,我假设您的类正在实现问题代码中缺少的 INotifyPropertyChanged:
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
Dispatcher uiDispatcher = Application.Current != null ? Application.Current.Dispatcher : null;
if (uiDispatcher != null)
{
uiDispatcher.BeginInvoke(DispatcherPriority.DataBind,
(ThreadStart)delegate()
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
});
}
}
}
然后在您的 CurrentMode 的 Setter 中调用 NotifyPropertyChanged("CurrentMode")。您可能已经需要这样的东西,因为您的 Server 的 ModeChanged 调用可能是在不是 Dispatcher 线程的线程上进入的。
最后,如果您希望它们具有不同的选中/未选中外观,则需要将样式应用于您的 RadioButtons。谷歌快速搜索 WPF RadioButton ControlTemplate 最终找到了这个网站: http: //madprops.org/blog/wpf-killed-the-radiobutton-star/。