2011-04-14 220 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/