Установите / снимите отметку со всех CheckBox в «CheckListBox» только в XAML - PullRequest
0 голосов
/ 21 февраля 2012

Я искал эту тему и нашел несколько обсуждений. Что мне не понравилось в этих реализациях, так это то, что они либо подразумевали специальный вид связанных данных (со свойством IsSelected), либо не имели нормальной поддержки клавиатуры.

CheckBox в списке - скорее декоративная вещь, нежели расширение функциональности, поэтому с ним следует обращаться соответствующим образом.

Я начал с этой милой и полезной статьи: http://www.gbogea.com/2010/01/02/mvvm-multiselect-listbox

Но я верю, что взлом View в пользу 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 не знает об особенностях связанных данных.

Это нормально. Но есть ли способ добавить Select | Deselect All для ListBox, добавив еще один флажок в шаблон элемента управления? Использование только XAML.

1 Ответ

1 голос
/ 21 февраля 2012

Вы можете сделать что-то подобное, используя, например, Interactivity из Blend SDK

<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 и преобразователя значений, чтобы привести его в правильное состояние, затем вы также можете сбросить события. Это также довольно грязно, хотя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...