我想呈现几个ToggleButton / RadioButton元素:
例如,4个按钮将显示以下视图模型:
public class ViewModel
{
public enum Mode { Idle, Active, Disabled, Running }
Mode m_currentMode = Mode.Idle;
public Mode CurrentMode
{
get { return m_currentMode; }
set
{
SendRequest(value);
}
}
// Called externally after SendRequest, not from UI
public void ModeChanged(Mode mode)
{
m_currentMode = mode;
NotifyPropertyChanged("CurrentMode");
}
}
我最初的方法是使用How to bind RadioButtons to an enum?中的解决方案,但这还不够,因为按钮状态会立即更改,即使我没有在setter中调用NotifyPropertyChanged。另外,我不喜欢“GroupName”黑客。
有什么想法吗?我不介意创建一个自定义按钮类,因为我需要很多按钮来表示多个视图。
我正在使用.NET 3.5 SP1和VS2008。
答案 0 :(得分:0)
如果你想使用RadioButtons,你只需要做一些小的调整来解决RadioButton的默认行为。
您需要解决的第一个问题是RadioButtons基于其常见的直接父容器自动分组。由于你不喜欢“GroupName”hack,你的另一个选择是将每个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”)。您可能已经需要这样的东西,因为您的服务器的ModeChanged调用可能是在不是Dispatcher线程的线程上进行的。
最后,如果您希望它们具有不同的Checked / Unchecked外观,则需要将样式应用于RadioButtons。快速谷歌搜索WPF RadioButton ControlTemplate最终提出了这个网站:http://madprops.org/blog/wpf-killed-the-radiobutton-star/。