WPF ComboBox 禁用时不显示任何选定内容 (IsEnabled == false)
我正在考虑不同的方法,让 WPF ComboBox
显示空白,就好像当 IsEnabled
设置为 false 时没有选择任何内容。像往常一样,我试图在不必重新定义 ComboBox 的整个控件模板的情况下执行此操作,这始终是我在 WPF 中遇到的一个难题。如果有人有比重新定义整个 ComboBox
控件模板更优雅的解决方案,请告诉我。
我想要做的原因是我有一个代表“全部”选项的 CheckBox
,选中时它会禁用用于仅选择一个的 ComboBox
单个项目。如果我的 CheckBox
被选中,有时用户会在看到 ComboBox
中剩余的值时感到困惑,因为该值在 UI 的该状态下没有任何意义。
另一个要求是解决方案不能修改 ComboBox
的 SelectedValue
、SelectedIndex
或 SelectedItem
值,因为我会喜欢在用户取消选中“全部”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>
I'm thinking out different ways to have a WPF ComboBox
show blank as if nothing is selected when IsEnabled
is set to false. Like always I'm trying to do this without having to redefine the whole control template for the ComboBox
which is always a struggle I have with WPF. If anybody has any solutions more elegant than redefining the whole ComboBox
control template please let me know.
The reason for what I'm trying to do is I have a CheckBox
that represents an "All" option and when checked it disables the ComboBox
which is used to pick only a single individual item. If my CheckBox
is checked it is sometimes confusing to the users to see a value remaining in the ComboBox
since that value has no meaning in that state of the UI.
Another requirement is that the solution cannot modify the SelectedValue
, SelectedIndex
, or SelectedItem
values of the ComboBox
since I would like to retain the previuosly selected item in the case that the users unchecks the "All" CheckBox
.
Solution based on HCL's answer:
<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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以使用触发器执行某些操作:
尝试在禁用该框时将
ItemTemplate
设置为空的DataTemplate
。这将影响所选项目的渲染并因此将其隐藏。另一个简单但不是很好的解决方案是将前景色设置为与背景色相同。
You can do something with triggers:
Try setting the
ItemTemplate
to an emptyDataTemplate
when the box is disabled. This will affect the rendering of the selected item and therefore hide it.Another simple but not very nice solution would be to set the foreground color to the same as a background color.
我相信您可以使用样式来完成此操作,而不是重新定义控件模板。使用 IsEnabled 属性上的触发器来设置组合框中显示的文本。更改 SelectedItem 将是我的第一个方法,但由于您不想这样做,因此您可能会发现成功设置 DisplayMemberPath。像这样的东西(未经测试)...
I believe you can do this with a Style, rather than redefining the control template. Use a Trigger on the IsEnabled property to set the text shown in the ComboBox. Altering the SelectedItem would be my first approach, but since you don't want to do that, you may find success setting the DisplayMemberPath. Something like this (untested)...
这是一种可以满足您需求的样式。它采用了我一直使用的一种技术:包含控件的多个版本的网格,以及确保在任何时间只有一个版本可见的数据触发器。
这将按照您的需要保留所选项目、所选索引和所选值。事实上,它在这方面做得有点太好了。实际上没有办法告诉用户已停用组合框,因为
ComboBox
上没有公开此信息的属性。我实际上可能会将其实现为从ComboBox
派生的自定义控件,该控件将复选框的值公开为IsActive
属性。还有很多其他方法可以做到这一点。Here's a style that does what you want. It employs a technique that I use all the time: a grid that contains multiple versions of the control, and data triggers that ensure that only one version is visible at any one time.
This preserves the selected item, selected index, and selected value, just as you want. In fact, it does this a little too well; there's not actually a way of telling that the user deactivated the combo box, since there's no property on
ComboBox
that exposes this information. I'd probably actually implement this as a custom control derived fromComboBox
that exposed the value of the check box as anIsActive
property. There are lots of other ways to do it.