Использовать флажок как кнопку-переключатель в расширителе

Я совершенно новичок в wpf и должен решить следующую проблему.

Мне нужно создать список (я использую список) элементов, которые можно расширить (расширить). Проблема в том, что их можно расширить, только если они были «выбраны». Каждый элемент списка должен иметь флажок и некоторый текст.

Итак, очень простой пример, чтобы проиллюстрировать, что я имею в виду:

<listbox>
<item>(checkbox) John Doe</item>
<item>(checkbox) Mike Murray</item>
</listbox>

Если установлен какой-либо (поэтому разрешено несколько) флажков в списке, элемент расширяется, показывая больше данных.

Опять пример:

<listbox>
<item>
   (checkbox-checked) John Doe
   Some extra data shown in expanded area
</item>
<item>
   (checkbox-unchecked) Mike Murray</item>
</listbox>

Я не могу заставить расширитель использовать флажок в качестве «переключателя».

Может ли кто-нибудь помочь мне? Некоторый пример кода был бы очень кстати...


person Shatish    schedule 01.12.2010    source источник


Ответы (2)


Это должно помочь:

<ListBox>
    <ListBox.Resources>
        <Style TargetType="Expander">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Expander">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>

                            <CheckBox
                                IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
                                Content="{TemplateBinding Header}"
                                />
                            <ContentControl
                                x:Name="body"
                                Grid.Row="1" Content="{TemplateBinding Content}"
                                />
                        </Grid>

                        <ControlTemplate.Triggers>
                            <Trigger Property="IsExpanded" Value="False">
                                <Setter TargetName="body" Property="Visibility" Value="Collapsed" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    </ListBox.Resources>

    <Expander Header="One">
        Content one
    </Expander>

    <Expander Header="Two">
        Content two
    </Expander>
</ListBox>

Здесь я определил Style, который изменяет Template любых Expander элементов управления, к которым применяется Style. (И так как я поместил Style в ListBox.Resources, он будет автоматически применен к элементам управления Expander в списке.)

Хитрость в том, чтобы заставить CheckBox работать, заключается в том, что когда вы помещаете его (или любой элемент управления на основе ToggleButton) в шаблон Expander, вам нужно использовать привязку данных, настроенную с его RelativeSource, установленным на TemplatedParent. Это обеспечивает двустороннюю привязку — это означает, что CheckBox не только отражает текущее состояние расширителя, но и может изменить текущее состояние.

person Ian Griffiths    schedule 02.12.2010
comment
Привет Ян, большое спасибо за ваш ответ. У меня работает ваш пример, а также он работает (в некоторой степени) в моем приложении. У меня есть еще один вопрос, и я надеюсь, что вы могли бы помочь с ним тоже. Учитывая настройку исходного вопроса, список с флажком в качестве переключателя, я использую его для отображения списка клиентов. Моя следующая проблема следующая: Некоторых клиентов нужно предварительно отобрать (например: если клиенту › 18 лет, по умолчанию = проверено, при загрузке формы) Можно ли это сделать (и возможно ли через привязка?) - person Shatish; 03.12.2010
comment
Да, определенно возможно. Я предполагаю, что вы используете ItemTemplate на практике и что Expander находится там. (И если вы этого не сделаете, вам следует!) В вашей ViewModel вам понадобится класс модели представления для каждого элемента, поэтому ваша основная модель представления может предоставить список моделей представления для каждого элемента, чтобы действовать как ItemSource вашего списка. А затем просто привяжите свойство IsExpanded Expander к логическому свойству модели представления для каждого элемента. - person Ian Griffiths; 03.12.2010
comment
У меня нет класса viemodel для каждого элемента для элементов в списке (пока), я попробую это. Теперь у меня есть привязка свойства IsExpanded расширителя к свойству в модели представления моей текущей формы/представления, но почему-то я не могу получить доступ/найти это свойство. Когда я пишу: IsExpanded=True, все работает отлично. Когда я пишу IsExpanded={Binding Path=PropertyNameThatGivesBooleanForSelected} (или без Path=), это не работает. Свойство никогда не читается. Я попробую модель представления для каждого элемента, как вы сказали, но на самом деле я ожидал, что то, что у меня есть сейчас, также будет работать. - person Shatish; 03.12.2010
comment
Я только что создал модель представления для каждого элемента, как вы сказали, и теперь она отлично работает! Большое спасибо за вашу помощь! - person Shatish; 03.12.2010

Все, что вам нужно, чтобы добавить флажок в заголовок, это этот код:

            <telerik:RadExpander.Header>
                <StackPanel Orientation="Horizontal">
                    <CheckBox VerticalAlignment="Center"/>
                    <TextBlock Margin="5,0,0,0">Legend</TextBlock>
                </StackPanel>
            </telerik:RadExpander.Header>

Я использую Rad Control, то же самое можно сделать с помощью стандартного расширителя

person Biondo86    schedule 12.12.2012