我在我的项目中使用此ObservableCollection-Class:Link
我想将RibbonMenuButton绑定到ObservableDictionary<string,bool>
:
<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}]}"/>
但这不会起作用{Binding} {绑定}的原因......
答案 0 :(得分:3)
这不起作用,因为您的字典不被视为字典而是IEnumerable<KeyValuePair<string, bool>>
。因此,每个RibbonMenuItem
都绑定到KeyValuePair<string, bool>
,其中包含只读属性Key
和Value
。
你可以做两个一件事 s :
1.使用 ObservableCollection<Tuple<string, bool>>
代替字典并将IsChecked
绑定到Item2
。
2.创建一个包含IsChecked
属性的小助手类,并更改字典以包含该类作为值,并将IsChecked
绑定到Value.IsChecked
。
我会回答二,因为所需的变化和可能的副作用较小
我的回答是假设您希望在IsChecked
上进行双向绑定。如果没有,请使用slugster的答案。
答案 1 :(得分: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(具体检查靠近页面底部的绑定模式部分)
答案 2 :(得分:1)
如果您想在不使用帮助程序类的情况下将MenuItems
绑定到Dictionary<string, bool>
,就像接受的答案所示,这里是 minimal-change 解决方案(无需添加其他任何事情):
Click
内定义ItemContainerStyle
事件,ClickEventHandler
将更新dicitonary。在代码中:
MainWindow.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
就是这样!你们都准备好了!
对于OneWay绑定的XAML代码,slugster and his answer的积分:)
答案 3 :(得分:0)
作为绑定到字典的这个问题的一般解决方案,我创建了一个UpdateableKeyValuePair并返回通常的KeyValuePair的instaed。这是我的班级:
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;
}
}
}