2012-09-22 54 views
0

我想在我的視圖中表達一個枚舉屬性作爲一組單選按鈕在我的視圖中。到現在爲止還挺好;我可以表達與雙向MultiBindingInverted TwoWay-MultiBinding

(rb1.IsChecked,rb2.IsChecked,rb3.IsChecked)< - > vm.Value

多部位裝訂這裏使用功能會一個多轉換器,可在(bool, bool, bool) <-> MyValue之間轉換;顯然,MyValue類型的(三個)允許值中的一個是基於哪個booltrue而被選擇的,反之亦然。

雖然這已經有點不方便:我無法在視圖的Xaml中定義該綁定,因爲必須從單個值的一側定義多綁定。因此,我必須在代碼隱藏中定義多重綁定,並使用SetBinding將其設置在我的視圖模型的Value屬性中。

現在,我堅持的問題是,我不只是綁定一組單選按鈕到該值,而是兩個。因此,我的綁定必須是這樣的:

(rbA1.IsChecked,rbA2.IsChecked,rbA3.IsChecked)< - > vm.Value < - >(rbB1.IsChecked,rbB2.IsChecked,rbB3。器isChecked)

的問題是,我不能使用SetBinding幾個綁定一次連接到vm.Value。我迄今試圖

解決辦法是:

  • 使用一個多結合,同時結合所有單選按鈕。這將意味着形式(rbA1.IsChecked, rbA2.IsChecked, rbA3.IsChecked, rbB1.IsChecked, rbB2.IsChecked, rbB3.IsChecked) <-> vm.Value的綁定。這個解決方案的問題是,如果其中一個單選按鈕(如rbB2)被選中,我無法判斷rbA2(未選中)或rbB2(選中)是否具有「新的正確」值。
  • 通過定義一個無線電組來首先抽象出單選按鈕組,該控件僅公開一個SelectedIndex屬性。然後,該屬性可以方便地綁定到我的vm.Value屬性,該屬性來自我的無線電組控件的所有實例。雖然可行,但它需要編寫一個新的控制類,我想知道這是否是WPF中唯一的方法。
  • 綁定一組單選按鈕,另外一個:通過雙向結合rbB1rbA1rbB2rbA2,等等,並使用我的vm.Value,只有第一組單選按鈕,我之間的多結合會達到預期的效果,但我不喜歡擁有「主無線電組」的想法。它會濫用GUI元素進行數據傳輸。
  • 盡一切代碼隱藏和手動更新單選按鈕和視圖模型的值。當然這是一個可行的後備解決方案,但是這個感覺像Xaml /帶綁定那樣應該是可行的。
+0

「使用一個大的多重綁定」,我不太明白。你有兩個radioButton組。您可以從group1中選擇一個項目,並且您可以從group2中選擇一個項目。我不明白'有新的正確價值'。 –

+0

@ChrisDD:「大型多重綁定」將一次綁定「vm.Value」和全部六個單選按鈕。六個單選按鈕可以有一個初始狀態,例如'(1,0,0,1,0,0)'。現在,讓我們說有人點擊第二組中的第二個單選按鈕,所以我的多轉換器可以用'(1,0,0,0,1,0)'調用。我該如何確定第一組或第二組是否正確,即應返回第一枚枚舉值還是第二枚枚舉值?據我所知,這並不方便。 –

+0

爲什麼你不使用單個綁定每個RadioButton?也使用轉換器和命令參數。例如:IsChecked = {綁定VMEnum,轉換器= {StaticResource toEnum},ConverterParameter = {YourEnum:FirstButtonChecked}}。你需要實現雙向轉換器。 無論哪種方式IsChecked = VMEnum ==(CommandParameter as Enum)[單向] –

回答

0

綁定VMEnum到每個單選按鈕seperately(使用單雙向綁定)。每個綁定應該有CommandParameter它是枚舉。像:

<RadioButton IsChecked="{Binding VMEnum, Converter={StaticResource EnumConverter}, ConverterParameter={Enums:VMEnums.FirstRadioButtonGroupA}}" /> 

在轉換器,

  • 轉換應該返回正確的值(真/假)取決於VMEnum和COmmandParameter的。本質上邏輯是VMEnum ==(YourEnum)CommandParameter。
  • ConvertBack應基於IsChecked返回正確的Enum。如果IsChecked爲true,則返回正確的枚舉。否則返回Binding.DoNothing這將中止該特定情況下的綁定。
+0

'Binding.DoNothing'是我失蹤的作品! –

0

對轉換器和代碼隱藏使用複雜的多重綁定不僅會使您的代碼更難調試,而且更難以測試。在我看來,最好將每組單選按鈕(標誌)表示爲視圖模型。當任何單選按鈕被選中/取消選中時,評估您的值。

的RadioButtonGroup

public class RadioButtonGroup : ViewModel { 

    public RadioButtonGroup(string groupName, int count, Action<bool[]> whenAnyChanaged = null) { 

     RadioButtons = Enumerable.Range(0, count).Select(_ => { 
      var button = new RadioButton { GroupName = groupName }; 
      button.PropertyChanged += (s, e) => { 
       if (e.PropertyName == "IsChecked") 
        whenAnyChanaged(Flags); 
      }; 
      return button; 
     }).ToList();   
    } 

    public List<RadioButton> RadioButtons { get; private set; } 

    public bool[] Flags { get { return RadioButtons.Select(rb => rb.IsChecked).ToArray(); } } 
} 

單選按鈕

public class RadioButton : ViewModel { 

    private bool isChecked; 

    public bool IsChecked { 
     get { return isChecked; } 
     set { SetProperty(ref this.isChecked, value); } 
    } 

    public string GroupName { get; set; } 
} 

MainViewModel

public class MainViewModel : ViewModel { 
    public MainViewModel() { 
     GroupA = new RadioButtonGroup("A", 10, flags => GroupToggle(flags, GroupB.Flags)); 
     GroupB = new RadioButtonGroup("B", 10, flags => GroupToggle(GroupA.Flags, flags)); 
    } 

    public RadioButtonGroup GroupA { get; private set; } 

    public RadioButtonGroup GroupB { get; private set; } 

    void GroupToggle(bool[] groupA, bool[] groupB) { 
     MyValue = Evaluate(groupA, groupB); 
    } 
} 

查看

<Window x:Class="WpfLab.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="{Binding Title}" Height="350" Width="525"> 
<Window.Resources> 
    <DataTemplate x:Key="RadioButton"> 
     <RadioButton IsChecked="{Binding IsChecked, Mode=OneWayToSource}" GroupName="{Binding GroupName}"/> 
    </DataTemplate> 
</Window.Resources> 
<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="30"/> 
     <RowDefinition Height="30"/> 
    </Grid.RowDefinitions> 

    <ListBox Grid.Row="0" ItemsSource="{Binding GroupA.RadioButtons}" ItemTemplate="{StaticResource ResourceKey=RadioButton}"> 
     <ListBox.ItemsPanel> 
      <ItemsPanelTemplate> 
       <StackPanel Orientation="Horizontal"/> 
      </ItemsPanelTemplate> 
     </ListBox.ItemsPanel> 
    </ListBox> 

    <ListBox Grid.Row="1" ItemsSource="{Binding GroupB.RadioButtons}" ItemTemplate="{StaticResource ResourceKey=RadioButton}"> 
     <ListBox.ItemsPanel> 
      <ItemsPanelTemplate> 
       <StackPanel Orientation="Horizontal"/> 
      </ItemsPanelTemplate> 
     </ListBox.ItemsPanel> 
    </ListBox> 
</Grid> 

+0

你在'MainViewModel'類中調用了什麼'Evaluate'方法?特別是,當「RadioButtonGroup」的狀態是例如'(1,0,0); (0,1,0)',它是如何知道'(1,0,0)'還是'(0,1,0)'是否是預期的新狀態? –

+0

現在它可能不會,但你可以添加Enum,例如「哪個組被改變了」並將它添加到GroupToggle並修改委託(MainiewModel())+將它傳遞給Evaluate。 –

+0

@ChrisDD:我認爲問題在於,在調用Evaluate的時候,已經知道哪些組發生了變化已經是未知的/太晚了。 –

相關問題