绑定复选框的 IsChecked 动态列表 属性
Binding dynamic list of CheckBoxes' IsChecked property
我遇到了从 SQL 数据库加载对象列表的情况。对于每个对象,我想在 ItemsControl
中显示一个 CheckBox
并且当且仅当其成员为 IsChecked
属性 绑定到 true
window 的 DataContext
在列表中包含该对象。
让我们打电话给我的 window MyWindow
。 MyWindow
的 DataContext
是一个 MyContext
类型的对象,它有一个 DataObject
类型的对象列表(从数据库加载)和一个 [=23] 类型的对象=]:
public class MyContext {
public Item CurrentItem { get; set; }
public List<DataObject> Data { get; set; }
}
public class Item {
public List<DataObject> CheckedDataObjects { get; set; }
}
在 MyWindow.xaml
中,我的 ItemsControl
绑定到 Data
列表。 ItemTemplate
定义每个 DataObject
都应显示一个 CheckBox
,当且仅当包含特定 DataObject
时,它的 IsChecked
应绑定为真在 MyWindow.DataContext.CurrentItem.CheckedDataObjects
.
我最好的想法是使用 IMultiValueConverter
方法,但是我得到一个带有内部 InvalidOperationException
的 XamlParseException
,说双向绑定需要 Path 或 XPath(松散翻译).请指教!
<ItemsControl ItemsSource="{Binding Data}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox>
<CheckBox.IsChecked>
<MultiBinding Converter="{StaticResource MyItemHasDataObjectConverter}">
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type local:MyWindow}}" Path="DataContext.CurrentItem"/>
<Binding RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
</CheckBox.IsChecked>
</CheckBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
public class ItemHasDataObjectConverter : IMultiValueConverter {
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
// values should contain two objects: the CurrentItem object and an object of type DataObject
if (values.Length == 2 && values[0] is Item && values[1] is DataObject) {
return (values[0] as Item).CheckedDataObjects.Contains(values[1] as DataObject);
}
return false;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
return null;
}
}
编辑
在 Aabid 的下面回答之后,转换器现在似乎可以正常工作了。此外,我已将 Checked
和 Unchecked
事件处理程序添加到 CheckBox
对象,add/remove 来自 CurrentItem.CheckedDataObjects
的相应 DataObject
对象。但是,如果我通过隐藏代码重置 CurrentItem.CheckedDataObjects
,通过调用 Clear()
或设置 CheckedDataObjects = new List<DataObject>()
,CheckBox
不会在 UI 中更新(它们保留检查)。
我已确保 MyContext
和 Item
实现 INotifyPropertyChanged
并触发相应的 OnPropertyChanged
方法。
将 Path=DataContext 属性 添加到多值绑定中的第二个绑定,即
<Binding Path=DataContext RelativeSource="{RelativeSource Self}"/>
我遇到了从 SQL 数据库加载对象列表的情况。对于每个对象,我想在 ItemsControl
中显示一个 CheckBox
并且当且仅当其成员为 IsChecked
属性 绑定到 true
window 的 DataContext
在列表中包含该对象。
让我们打电话给我的 window MyWindow
。 MyWindow
的 DataContext
是一个 MyContext
类型的对象,它有一个 DataObject
类型的对象列表(从数据库加载)和一个 [=23] 类型的对象=]:
public class MyContext {
public Item CurrentItem { get; set; }
public List<DataObject> Data { get; set; }
}
public class Item {
public List<DataObject> CheckedDataObjects { get; set; }
}
在 MyWindow.xaml
中,我的 ItemsControl
绑定到 Data
列表。 ItemTemplate
定义每个 DataObject
都应显示一个 CheckBox
,当且仅当包含特定 DataObject
时,它的 IsChecked
应绑定为真在 MyWindow.DataContext.CurrentItem.CheckedDataObjects
.
我最好的想法是使用 IMultiValueConverter
方法,但是我得到一个带有内部 InvalidOperationException
的 XamlParseException
,说双向绑定需要 Path 或 XPath(松散翻译).请指教!
<ItemsControl ItemsSource="{Binding Data}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox>
<CheckBox.IsChecked>
<MultiBinding Converter="{StaticResource MyItemHasDataObjectConverter}">
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type local:MyWindow}}" Path="DataContext.CurrentItem"/>
<Binding RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
</CheckBox.IsChecked>
</CheckBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
public class ItemHasDataObjectConverter : IMultiValueConverter {
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
// values should contain two objects: the CurrentItem object and an object of type DataObject
if (values.Length == 2 && values[0] is Item && values[1] is DataObject) {
return (values[0] as Item).CheckedDataObjects.Contains(values[1] as DataObject);
}
return false;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
return null;
}
}
编辑
在 Aabid 的下面回答之后,转换器现在似乎可以正常工作了。此外,我已将 Checked
和 Unchecked
事件处理程序添加到 CheckBox
对象,add/remove 来自 CurrentItem.CheckedDataObjects
的相应 DataObject
对象。但是,如果我通过隐藏代码重置 CurrentItem.CheckedDataObjects
,通过调用 Clear()
或设置 CheckedDataObjects = new List<DataObject>()
,CheckBox
不会在 UI 中更新(它们保留检查)。
我已确保 MyContext
和 Item
实现 INotifyPropertyChanged
并触发相应的 OnPropertyChanged
方法。
将 Path=DataContext 属性 添加到多值绑定中的第二个绑定,即
<Binding Path=DataContext RelativeSource="{RelativeSource Self}"/>