绑定复选框的 IsChecked 动态列表 属性

Binding dynamic list of CheckBoxes' IsChecked property

我遇到了从 SQL 数据库加载对象列表的情况。对于每个对象,我想在 ItemsControl 中显示一个 CheckBox 并且当且仅当其成员为 IsChecked 属性 绑定到 true window 的 DataContext 在列表中包含该对象。

让我们打电话给我的 window MyWindowMyWindowDataContext 是一个 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 方法,但是我得到一个带有内部 InvalidOperationExceptionXamlParseException,说双向绑定需要 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 的下面回答之后,转换器现在似乎可以正常工作了。此外,我已将 CheckedUnchecked 事件处理程序添加到 CheckBox 对象,add/remove 来自 CurrentItem.CheckedDataObjects 的相应 DataObject 对象。但是,如果我通过隐藏代码重置 CurrentItem.CheckedDataObjects,通过调用 Clear() 或设置 CheckedDataObjects = new List<DataObject>()CheckBox 不会在 UI 中更新(它们保留检查)。

我已确保 MyContextItem 实现 INotifyPropertyChanged 并触发相应的 OnPropertyChanged 方法。

将 Path=DataContext 属性 添加到多值绑定中的第二个绑定,即

 <Binding Path=DataContext RelativeSource="{RelativeSource Self}"/>