如何基于列表中绑定对象的存在设置CheckBox.IsChecked

Gre*_*som 5 .net data-binding wpf checkbox observablecollection

有2个列表-AvailableItems和SelectedItems。

AvailableItems显示在一个ListBox中,并且每个ListBoxItem都包含一个CheckBox。目的是检查绑定项目是否在SelectedItems中的CheckBox。

是否可以在不处理后面代码中的“选中”和“未选中”且没有将IsSelected属性添加到我的项目类的情况下实现此目的?

到目前为止,这是XAML:

   <ListBox Name="ListBox1" ItemsSource="{Binding Path=AvailableItems}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel></StackPanel>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <DockPanel>
                    <CheckBox Name="cb1"></CheckBox>
                    <TextBlock Text="{Binding}"></TextBlock>
                </DockPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ListBox>
Run Code Online (Sandbox Code Playgroud)

和背后的代码:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            _availableItems.Add(Colors.Red);
            _availableItems.Add(Colors.Green);
            _availableItems.Add(Colors.Blue);

            _selectedItems.Add(Colors.Green);

            this.DataContext = this;
        }

        ObservableCollection<Color> _selectedItems = new ObservableCollection<Color>();
        public ObservableCollection<Color> SelectedItems
        {
            get { return _selectedItems; }
            set { _selectedItems = value; }
        }

        ObservableCollection<Color> _availableItems = new ObservableCollection<Color>();
        public ObservableCollection<Color> AvailableItems
        {
            get { return _availableItems; }
            set { _availableItems = value; }
        }
    }
Run Code Online (Sandbox Code Playgroud)

上面的xaml /代码可以直接复制到新的WPF项目中进行测试。

Ric*_*key 5

您定义了一个多值转换器,它接受一个项目和一个集合并返回一个布尔值:

public class CollectionContainsConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var item = values[0];
        var collection = values[1] as IList;
        return collection.Contains(item);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你像这样使用它:

    <ListBox Name="ListBox1" ItemsSource="{Binding Path=AvailableItems}">
        <ListBox.Resources>
            <local:CollectionContainsConverter x:Key="contains"/>
        </ListBox.Resources>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel></StackPanel>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <DockPanel>
                    <CheckBox Name="cb1">
                        <CheckBox.IsChecked>
                            <MultiBinding Converter="{StaticResource contains}" Mode="OneWay">
                                <Binding Mode="OneWay"/>
                                <Binding ElementName="ListBox1" Path="DataContext.SelectedItems" Mode="OneWay"/>
                            </MultiBinding>
                        </CheckBox.IsChecked>
                    </CheckBox>
                    <TextBlock Text="{Binding}"></TextBlock>
                </DockPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ListBox>
Run Code Online (Sandbox Code Playgroud)

处理反向转换留作练习。