2

我正在考虑让 WPFComboBox显示为空白的不同方法,就好像在IsEnabled设置为 false 时没有选择任何内容一样。像往常一样,我试图做到这一点,而不必重新定义整个控件模板,ComboBox这一直是我与 WPF 的斗争。如果有人有比重新定义整个ComboBox控件模板更优雅的解决方案,请告诉我。

我要做的事情的原因是我有一个CheckBox代表“所有”选项的代表,并且在检查时,它会禁用ComboBox仅选择单个项目的方法。如果我CheckBox被选中,有时用户会混淆看到剩余的值ComboBox因为该值在 UI 的该状态下没有任何意义。

另一个要求是解决方案不能修改SelectedValueSelectedIndexSelectedItem的值,ComboBox因为我想在用户取消选中 "All" 的情况下保留先前选择的项目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>
4

3 回答 3

1

你可以用触发器做一些事情:

禁用该框时,尝试将 ItemTemplate 设置为空的 DataTemplate。这将影响所选项目的呈现,因此将其隐藏。
另一个简单但不是很好的解决方案是将前景色设置为与背景色相同。

于 2011-01-19T21:11:55.623 回答
0

我相信您可以使用样式来做到这一点,而不是重新定义控件模板。使用 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>
于 2011-01-19T21:18:31.190 回答
0

这是一种风格,可以满足您的需求。它采用了我一直使用的一种技术:一个包含多个控件版本的网格,以及确保在任何时候只有一个版本可见的数据触发器。

    <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属性公开。还有很多其他方法可以做到这一点。

于 2011-01-19T23:24:26.243 回答