将复选框列表绑定到已检查值列表的最简单方法是什么

Ant*_*ien 11 wpf binding

我有一个列表AvailableItems,我想显示为一个复选框列表,以便用户可以选择要生成的项目,然后存储在另一个名为的ItemsToGenerate列表中(我的列表实际上只是字符串列表).

显示包含相应复选框的所有可用项目很简单:

<ItemsControl ItemsSource="{Binding Path=AvailableItems}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <CheckBox Content="{Binding}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>    
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)

但是现在我需要将每个Checkbox.IsChecked属性绑定到项目在ItemsToGenerate列表中的事实.我想到ListContainmentToBoolConverter这样做:

IsChecked="{Binding Path=ItemsToGenerate, 
            Converter={StaticResource ListContainmentToBoolConverter}}"
Run Code Online (Sandbox Code Playgroud)

但这不起作用,因为我错过了ConverterParameter传递每个项目的值,但我不能这样做,因为ConverterParameter不支持绑定.

有任何想法吗?

Ant*_*ien 13

我找到了解决问题的方法.

我已将我ItemsControl改为a ListBox,并ItemsToGenerate使用此处描述的技术我的集合中添加了SelectedItems之间的绑定.它基本上允许我将任何自定义集合同步到ListBox.SelectedItems使用简单的附加属性.

<ListBox ItemsSource="{Binding AvailableItems}"
         Behaviors:MultiSelectorBehaviours.SynchronizedSelectedItems=
             "{Binding ItemsToGenerate}"
         SelectionMode="Multiple"
         Background="{x:Null}">  
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel />                    
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <CheckBox Content="{Binding}"
                      Margin="3"
                      IsChecked="{Binding RelativeSource=
                           {RelativeSource Mode=FindAncestor,
                            AncestorType={x:Type ListBoxItem}},
                           Path=IsSelected}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ListBox>
Run Code Online (Sandbox Code Playgroud)

我仍然能够像我最初想要的那样(复选框列表)显示这一点,通过添加数据模板将每个模板更改ListBoxItem为复选框并将每个模板绑定Checkbox.IsCheckedListBoxItem.IsSelected.

我在我的应用程序中有很多这样的模式,这对我来说是理想的解决方案,因为现在我只需要指定一个附加属性,其余的都由数据绑定处理,我不需要任何额外的码.


Den*_*ler 10

老实说,我会创建一个包含字符串和布尔值的对象列表,指示是否选中它.

使用一点Linq,您可以生成对象列表并将其绑定到itemSource,而不是绑定字符串列表.

它最终会更简单,特别是如果您确实需要更新某些内容,如果允许用户选中/取消选中复选框.

==更新==

在回答评论时,我认为这是因为我不确定我理解实际问题是什么:只要我们有完整列表(AvailableItems)和所选项目列表(ItemsToGenerate):

public class ItemEntry
{
  public string Name { get; set; }
  public bool IsSelected {get; set; }
}
Run Code Online (Sandbox Code Playgroud)

...

_Items = from item in AvailableItems
            select new ItemEntry() { 
                    Name = item, 
                    IsSelected = ItemsToGenerate.contains(item)
                  }).ToList();
Run Code Online (Sandbox Code Playgroud)

然后,您可以将_Items公开为名为Items的属性,从而绑定您的列表:

<ItemsControl ItemsSource="{Binding Path=Items}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <CheckBox Content="{Binding Name}" IsChecked="{Binding IsSelected}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>    
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)

您可以稍后从_Items中选择IsSelected为true,以便在需要时获取所选项目.

此外,如果ItemsToGenerate可以变大,您应该创建值的HashSet并在查询中使用它,如果需要,它应该更快.