我正在考虑拥有WPF的不同方法 ComboBox 显示空白,好像什么都没选择 IsEnabled 设置为false。就像我往常一样,我不必重新定义整个控制模板 ComboBox 这总是我与WPF的斗争。如果有人拥有更优雅的解决方案,而不是重新定义整个解决方案 ComboBox 控制模板请告诉我。

我想做的是我有一个 CheckBox 代表一个“全”选项,检查时都会禁用 ComboBox 它仅用于选择一个单独的项目。如果我的话 CheckBox 被检查 ComboBox 由于该值在UI状态中没有意义。

另一个要求是解决方案无法修改 SelectedValue, SelectedIndex, , 或者 SelectedItem 值的值 ComboBox 由于我想保留在用户取消选中“全部”的情况下保留previuosled选项的项目 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>
有帮助吗?

解决方案

您可以使用触发器做某事:

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

其他提示

我相信您可以使用样式进行此操作,而不是重新定义控制模板。使用ISENABLE属性上的触发器设置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>

这是一种按照您想要的方式。它采用了我一直使用的技术:一个包含多个控件版本的网格,以及确保任何一次仅可见一个版本的数据触发器。

    <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 财产。还有许多其他方法可以做到。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top