仅在XAML中的“CheckListBox”中选择/取消选中所有CheckBox

时间:2012-02-21 14:02:35

标签: .net wpf xaml

我搜索了这个主题并找到了几个讨论。 我对这些实现不喜欢的是它们暗示了特殊类型的绑定数据(具有IsSelected属性)或缺少正常的键盘支持。

列表中的CheckBox更像是一个装饰性的东西,而不是functionalyty扩展,因此应该相应地对待它。

我从这篇精彩而有用的文章开始:http://www.gbogea.com/2010/01/02/mvvm-multiselect-listbox

但我相信黑客观点支持ViewModel并不是很好的做法。 ViewModel适用于View和Model。当然,恕我直言。

所以我改变了一点并完成了这个XAML:

<ListBox Name="checkboxList"
                 ItemsSource="{Binding Sports}"
                 Margin="0,5"
                 SelectionMode="Multiple">
            <ListBox.ItemContainerStyle>
                <Style>
                    <Setter Property="ListBoxItem.Background" Value="Transparent"/>
                    <Setter Property="ListBoxItem.Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                                <Border x:Name="Bd" 
                                SnapsToDevicePixels="true" 
                                Background="{TemplateBinding Background}" 
                                BorderBrush="{TemplateBinding BorderBrush}" 
                                BorderThickness="{TemplateBinding BorderThickness}"
                                Padding="{TemplateBinding Padding}">
                                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
                                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                </Border>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListBox.ItemContainerStyle>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <CheckBox IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected, Mode=TwoWay}" 
                              Content="{Binding}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

这里CheckBox选择与ListBoxItem.IsSelected同步,ListBox不知道绑定数据的特性。

这没关系。 但有没有办法通过向控件模板添加一个复选框来为ListBox添加Select | Deselect All?仅使用XAML。

1 个答案:

答案 0 :(得分:1)

你可以使用Blend SDK

中的Interactivity来做类似的事情
<ListBox ItemsSource="{Binding Data}" SelectionMode="Extended">
    <ListBox.Template>
        <ControlTemplate TargetType="ListBox">
            <StackPanel>
                <CheckBox Content="All">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="Checked">
                            <is:CallMethodAction MethodName="SelectAll"
                                    TargetObject="{Binding RelativeSource={RelativeSource TemplatedParent}}" />
                        </i:EventTrigger>
                        <i:EventTrigger EventName="Unchecked">
                            <is:CallMethodAction MethodName="UnselectAll"
                                    TargetObject="{Binding RelativeSource={RelativeSource TemplatedParent}}" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </CheckBox>
                <ItemsPresenter />
            </StackPanel>
        </ControlTemplate>  
    </ListBox.Template>
</ListBox>

然而,这并没有解决您没有提及或想到的问题,即在不使用它的情况下更改选择时CheckBox的状态不会改变。您可以使用IsChecked和值转换器绑定MultiBinding状态以使其进入正确状态,然后您也可以删除事件。但它也相当混乱。