2011-05-17 51 views
2

我用我的計劃之內這個的ObservableCollection級:Link
我想綁定RibbonMenuButton到ObservableDictionary<string,bool>WPF:綁定到一個(可觀察)字典

<r:RibbonMenuButton ItemsSource="{Binding MyDictionary}"> 
    <r:RibbonMenuButton.ItemContainerStyle> 
     <Style TargetType="{x:Type r:RibbonMenuItem}"> 
      <Setter Property="IsCheckable" Value="true"/> 
      <Setter Property="Header" Value="{Binding Path=Key}"/> 
      <Setter Property="IsChecked" Value="{Binding Path=Value}"/> 
     </style> 
    </r:RibbonMenuButton.ItemContainerStyle> 
</r:RibbonMenuButton> 

,但我得到的例外,因爲內部IDictionary-KeyValuePairs的Value-Properties屬性是隻讀的。任何想法如何解決這個問題?

我想過是這樣的:

<Setter Property="IsChecked" Value="{Binding Source=MyDictionary[{Binding Path=Key}]}"/> 

但是這是不行的「{}綁定在{結合}的原因...

回答

3

這是不行的,因爲你的字典ISN不被視爲字典,而是作爲IEnumerable<KeyValuePair<string, bool>>。因此,每個RibbonMenuItem都綁定到KeyValuePair<string, bool>,只讀屬性KeyValue
你可以做一件事小號

1.使用ObservableCollection<Tuple<string, bool>>而不是字典,並結合IsCheckedItem2
2.創建一個包含IsChecked屬性的小助手類,並更改字典以將該類包含爲值並將IsChecked綁定到Value.IsChecked

我會與答案二,因爲所需的變化和可能的副作用較小。
我的答案假定您想在IsChecked上有雙向綁定。如果沒有,請與slugster的答案一起。

+0

元組......這就是我正在尋找的類,工程PERFEKT我! – Reini 2011-05-17 11:51:06

+0

narf ... Touple.Item1/2也是隻讀的。所以我打算用輔助班,努力避免這種... – Reini 2011-05-17 11:58:21

+0

@Reini:哎呀。對不起...... – 2011-05-17 11:59:19

1

默認情況下WPF綁定是雙向的。單向製作並查看是否能解決您的問題。

<r:RibbonMenuButton ItemsSource="{Binding MyDictionary}"> 
    <r:RibbonMenuButton.ItemContainerStyle> 
     <Style TargetType="{x:Type r:RibbonMenuItem}"> 
      <Setter Property="IsCheckable" Value="true"/> 
      <Setter Property="Header" Value="{Binding Key, Mode=OneWay}"/> 
      <Setter Property="IsChecked" Value="{Binding Value, Mode=OneWay}"/> 
     </style> 
    </r:RibbonMenuButton.ItemContainerStyle> 
</r:RibbonMenuButton> 

這裏是您的引用:MSDN Windows Presentation Foundation Data Binding: Part 1(專門檢查綁定模式靠近頁的底部的部分

+0

將無法​​正常工作......我想將複選框的IsChecked狀態反映到我的ViewModel;) – Reini 2011-05-17 11:51:51

0

至於結合字典這個問題的一般解決方案我創建了一個UpdateableKeyValuePair並返回通常KeyValuePair的那個值。這裏是我的課:

public class UpdateableKeyValuePair<TKey,TValue> 
     { 
     private IDictionary<TKey, TValue> _owner; 
     private TKey _key; 
     public UpdateableKeyValuePair(IDictionary<TKey, TValue> Owner, TKey Key_) 
     { 
     _owner = Owner; 
     _key = Key_; 
     } 

     public TKey Key 
     { 
     get 
      { 
      return _key; 
      } 
     } 

     public TValue Value 
     { 
     get 
      { 
      return _owner[_key]; 
      } 
     set 
     { 
      _owner[_key] = value; 
     } 
     } 
    } 
1

如果你要綁定MenuItemsDictionary<string, bool>不使用輔助類,如接受的答案表明,這裏是微小病變解決方案(無需添加任何其他內容):

  • 定義ItemContainerStyleClickEventHandlerClick事件將更新dicitonary。
  • 聲明字典和初始化UserControl的/窗的構造

在代碼中:

主窗口。XAML:

<MenuItem Header="_My settings" ItemsSource="{Binding MySettings}"> 
    <MenuItem.ItemContainerStyle> 
     <Style TargetType="{x:Type MenuItem}"> 
     <Setter Property="IsCheckable" Value="true"/> 
     <Setter Property="Header" Value="{Binding Key, Mode=OneWay}"/> 
     <Setter Property="IsChecked" Value="{Binding Value, Mode=OneWay}"/> 
     <!-- this is the main line of code --> 
     <EventSetter Event="Click" Handler="MySettings_ItemClick"/> 
     </Style> 
    </MenuItem.ItemContainerStyle> 
</MenuItem> 

MainWindow.xaml.cs:

public partial class MainWindow : Window 
{ 
    // properties... 

    // Declaration of the dictionary 
    public Dictionary<string, bool> MySettings{ get; set; } 

    public MainWindow() 
    { 
     InitializeComponent(); 
     // Initialize the dictionary 
     MySettings = new Dictionary<string, bool>() 
     { 
      { "SettingOne", true} 
      // Other pairs.. 
     }; 
    } 
    // other things.. 

    // ClickEvent hanlder 
    private void MySettings_ItemClick(object sender, RoutedEventArgs e) 
    { 
     MenuItem clickedItem = (sender as MenuItem); 
     MySettings[clickedItem.Header as string] = clickedItem.IsChecked; 
    } 
} // end of MainWindow class 

這就是它!你們都準備好了!

slugster and his answer爲單向XAML代碼結合:)