WPF ComboBox, который не показывает ничего выбранного при отключении (IsEnabled == false) - PullRequest
2 голосов
/ 20 января 2011

Я думаю о разных способах отображения WPF ComboBox пустым, как будто ничего не выбрано, если для IsEnabled установлено значение false. Как всегда, я пытаюсь сделать это без необходимости переопределять весь шаблон управления для ComboBox, что всегда является борьбой, с которой я сталкиваюсь с WPF. Если у кого-нибудь есть какие-либо решения, более элегантные, чем переопределение всего шаблона управления ComboBox, пожалуйста, дайте мне знать.

Причиной того, что я пытаюсь сделать, является то, что у меня есть CheckBox, который представляет опцию "Все", и когда отмечен, он отключает ComboBox, который используется для выбора только одного отдельного элемента. Если мой CheckBox отмечен, пользователям иногда сложно увидеть значение, оставшееся в ComboBox, поскольку это значение не имеет значения в этом состоянии пользовательского интерфейса.

Другое требование состоит в том, что решение не может изменять значения SelectedValue, SelectedIndex или SelectedItem ComboBox, поскольку я хотел бы сохранить ранее выбранный элемент в случае, если пользователи снимут флажок «Все "CheckBox.

Решение, основанное на ответе HCL:

<ComboBox IsEnabled="{Binding ElementName=myCheckBox, Path=IsChecked}"
          ItemsSource="{Binding Path=MyItems}"
          SelectedValue="{Binding Path=MySelectedItem}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <ContentControl x:Name="content" Content="{Binding MyItemDescription}" />
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ComboBox}, Path=IsEnabled}"
                             Value="False">
                    <Setter TargetName="content"
                            Property="Visibility"
                            Value="Hidden" />
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

Ответы [ 3 ]

1 голос
/ 20 января 2011

Вы можете сделать что-нибудь с помощью триггеров:

Попробуйте установить ItemTemplate на пустой DataTemplate, когда поле отключено. Это повлияет на рендеринг выбранного элемента и, следовательно, скрыть его.
Другое простое, но не очень удачное решение - установить цвет переднего плана таким же, как цвет фона.

0 голосов
/ 20 января 2011

Вот стиль, который делает то, что вы хотите. В ней используется метод, который я использую постоянно: сетка, содержащая несколько версий элемента управления, и триггеры данных, которые гарантируют, что в любой момент времени видна только одна версия.

    <ComboBox.Style>
      <Style TargetType="ComboBox">
        <Setter Property="Template">
          <Setter.Value>
            <ControlTemplate TargetType="ComboBox">
              <DockPanel>
                <CheckBox x:Name="IsActive" DockPanel.Dock="Left"/>
                <Grid>
                  <ComboBox
                    ItemsSource="{TemplateBinding ItemsSource}"
                    SelectedItem="{TemplateBinding SelectedItem}"
                    SelectedIndex="{TemplateBinding SelectedIndex}"
                    SelectedValue="{TemplateBinding SelectedValue}">
                    <ComboBox.Style>
                      <Style TargetType="ComboBox">
                        <Setter Property="Visibility" Value="Visible"/>
                        <Style.Triggers>
                          <DataTrigger Binding="{Binding ElementName=IsActive, Path=IsChecked}" Value="False">
                            <Setter Property="Visibility" Value="Collapsed"/>
                          </DataTrigger>
                        </Style.Triggers>
                      </Style>
                    </ComboBox.Style>
                  </ComboBox>
                  <ComboBox>
                    <ComboBox.Style>
                      <Style TargetType="ComboBox">
                        <Setter Property="Visibility" Value="Collapsed"/>
                        <Style.Triggers>
                          <DataTrigger Binding="{Binding ElementName=IsActive, Path=IsChecked}" Value="False">
                            <Setter Property="Visibility" Value="Visible"/>
                          </DataTrigger>
                        </Style.Triggers>
                      </Style>
                    </ComboBox.Style>                      
                  </ComboBox>
                </Grid>
              </DockPanel>
            </ControlTemplate>
          </Setter.Value>
        </Setter>
      </Style>
    </ComboBox.Style>

Это сохраняет выбранный элемент, выбранный индекс и выбранное значение так, как вы хотите. На самом деле, это делает это слишком хорошо; на самом деле нет способа сообщить, что пользователь деактивировал поле со списком, поскольку в ComboBox нет свойства, предоставляющего эту информацию. Возможно, я бы на самом деле реализовал это как пользовательский элемент управления, полученный из ComboBox, который выставил значение флажка как свойство IsActive. Есть много других способов сделать это.

0 голосов
/ 20 января 2011

Полагаю, вы можете сделать это с помощью стиля, а не переопределять шаблон элемента управления. Используйте Trigger для свойства IsEnabled, чтобы установить текст, отображаемый в ComboBox. Изменение SelectedItem было бы моим первым подходом, но так как вы не хотите этого делать, вы можете найти успешную установку DisplayMemberPath. Как то так (не проверено) ...

<Style TargetType="{x:Type ComboBox}">
    <Style.Triggers>
        <Trigger Property="IsEnabled" Value="False">
            <Trigger.Setters>
                <Setter Property="DisplayMemberPath" Value="{x:Null}"/>
            </Trigger.Setters>
        </Trigger>
    </Style.Triggers>
</Style>
...