2011-04-14 221 views
3

我想提出几个切换按钮/单选按钮元素:更改切换按钮/单选按钮状态外部事件

  1. 映射到一个枚举,这意味着在DataContext具有“公共模式CURRENTMODE”属性。
  2. 是互斥的(只检查一个按钮)
  3. 当单击按钮时,状态不会立即改变。而是将请求发送到服务器。响应到达时状态会改变。
  4. 具有用于选中/取消状态不同的图像

例如,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?使用该解决方案,但这是不够的,因为即使我不在调用程序中调用NotifyPropertyChanged,也会立即更改按钮状态。另外,我不喜欢“GroupName”黑客。

任何想法?我不介意创建一个自定义按钮类,因为我需要多个按钮,像多个视图。

我使用.NET 3.5 SP1和VS2008。

回答

0

如果你想使用RadioButton,你只需做一些小的调整来解决RadioButton的默认行为。

您需要解决的第一个问题是基于它们的通用直接父容器自动对RadioButton进行分组。既然你不喜欢“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> 

这使我想到这是确保点击它后的按钮点击不留其选中状态下一个解决方法这是必要的,以触发集合调用,因为你是在装订器isChecked属性。您需要发送一个额外的NotifyPropertyChanged,但它必须被推入调度线程的队列中,以便该按钮将接收通知并更新其可视化IsChecked绑定。添加到您的视图模型类,这可能是替换现有的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的二传手呼吁NotifyPropertyChanged

然后(“CURRENTMODE “)。您可能已经需要类似这样的事情,因为您的服务器的ModeChanged调用可能是在不是Dispatcher线程的线程中进入的。

最后,如果您希望它们具有不同的Checked/Unchecked外观,您将需要将样式应用于您的RadioButtons。快速谷歌搜索WPF RadioButton ControlTemplate最终出现在这个网站:http://madprops.org/blog/wpf-killed-the-radiobutton-star/