当 WPF ComboBox 的选择为空时,它可以显示替代文本吗?
日安!
我希望我的 WPF ComboBox
在其数据绑定选择为 null
时显示一些替代文本。
视图模型具有预期的属性:
public ThingoSelectionViewModel : INotifyPropertyChanged {
public ThingoSelectionViewModel(IProvideThingos) {
this.Thingos = IProvideThingos.GetThingos();
}
public ObservableCollection<Thingo> Thingos { get; set; }
public Thingo SelectedThingo {
get { return this.selectedThingo; }
set { // set this.selectedThingo and raise the property change notification
}
// ...
}
视图以预期的方式将 XAML 绑定到视图模型:
<ComboBox x:Name="ComboboxDrive" SelectedItem="{Binding Path=SelectedThingo}"
IsEditable="false" HorizontalAlignment="Left" MinWidth="100"
IsReadOnly="false" Style="{StaticResource ComboboxStyle}"
Grid.Column="1" Grid.Row="1" Margin="5" SelectedIndex="0">
<ComboBox.ItemsSource>
<CompositeCollection>
<ComboBoxItem IsEnabled="False">Select a thingo</ComboBoxItem>
<CollectionContainer
Collection="{Binding Source={StaticResource Thingos}}" />
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>
楔入顶部的 ComboBoxItem
是在顶部获取额外项目的一种方式。它是纯粹的镀铬:视图模型保持纯粹和简单。只有一个问题:只要组合框的选择为空,用户就希望显示“选择一项”。
用户不希望默认选择某个事物。他们希望看到一条消息,告诉他们选择一个事物。
我希望避免使用 ThingoWrapper
类污染视图模型,该类的 ToString
方法返回“Select a thingo”(如果其 .ActualThingo
)属性为 null,在填充 Thingos
时包装每个 Thingo
,并找出某种方法来防止用户选择空的 Thingo
。
有没有办法使用纯 XAML 或纯 XAML 和视图代码隐藏类中的几行代码在 ComboBox
边界内显示“选择事物”?
G'day!
I want my WPF ComboBox
to display some alternative text when its data-bound selection is null
.
The view model has the expected properties:
public ThingoSelectionViewModel : INotifyPropertyChanged {
public ThingoSelectionViewModel(IProvideThingos) {
this.Thingos = IProvideThingos.GetThingos();
}
public ObservableCollection<Thingo> Thingos { get; set; }
public Thingo SelectedThingo {
get { return this.selectedThingo; }
set { // set this.selectedThingo and raise the property change notification
}
// ...
}
The view has XAML binding to the view model in the expected way:
<ComboBox x:Name="ComboboxDrive" SelectedItem="{Binding Path=SelectedThingo}"
IsEditable="false" HorizontalAlignment="Left" MinWidth="100"
IsReadOnly="false" Style="{StaticResource ComboboxStyle}"
Grid.Column="1" Grid.Row="1" Margin="5" SelectedIndex="0">
<ComboBox.ItemsSource>
<CompositeCollection>
<ComboBoxItem IsEnabled="False">Select a thingo</ComboBoxItem>
<CollectionContainer
Collection="{Binding Source={StaticResource Thingos}}" />
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>
The ComboBoxItem
wedged into the top is a way to get an extra item at the top. It's pure chrome: the view model stays pure and simple. There's just one problem: the users want "Select a thingo" displayed whenever the ComboBox' selection is null.
The users do not want a thingo selected by default. They want to see a message telling them to select a thingo.
I'd like to avoid having to pollute the viewmodel with a ThingoWrapper
class with a ToString
method returning "Select a thingo" if its .ActualThingo
property is null, wrapping each Thingo
as I populate Thingos
, and figuring out some way to prevent the user from selecting the nulled Thingo
.
Is there a way to display "Select a thingo" within the ComboBox
' boundaries using pure XAML, or pure XAML and a few lines of code in the view's code-behind class?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您的 MVVM 要求有多严格?您可以在视图中添加一些隐藏代码吗?
也许您可以将 ComboBox 包含在网格中,如下所示:
然后,在后面的代码中,在事件处理程序中插入一些逻辑:
在 TextBlock 上设置
IsHitTestVisible="False"
DependencyProperty 可以让鼠标事件通过,以便您可以单击 ComboBox,并且在隐藏代码中将可见性设置为Hidden
可以防止默认 ComboBox 外观的布局在提示文本隐藏时跳来跳去。How strict is your MVVM requirement? Can you have a little code-behind in the view?
Perhaps you could contain the ComboBox in a grid, something like this:
Then, in the code-behind, insert some logic in an event handler:
Setting the
IsHitTestVisible="False"
DependencyProperty on the TextBlock lets mouse events through so that you can click on the ComboBox, and setting the visibility toHidden
in the code-behind keeps the layout of a default ComboBox's appearance from jumping around when the prompt text is hidden.您不能使用控件模板触发器,但可以为组合框设置一个简单的项目模板:
You can't use a control template trigger, but you could set up a simple item template for the combobox:
编辑:
看来触发这个想法是行不通的。我将以下内容添加到测试组合框的控制模板中,但无济于事:
此外,当尝试在 Blend(编辑当前)中编辑控制模板时,我留下了一个毫无功能的组合框,没有颜色,只有一个丑陋的按钮(但有是一个无边框下拉菜单)。尝试别人的建议(也许是迈克·布朗)。
原文:
您可以在控件模板中使用触发器。这是一个使用我正在开发的应用程序中的列表框的示例。
上面的 ControlTemplate 有一个触发器,用于检查属性 HasItems。如果为 False,则在列表框的中间显示一个文本块“No Items”。如果有项目,则会显示它们。
在您的情况下,更改触发器以检查 ItemSelected 是否为 x:Null 并将 Text 属性设置为“Nothing Selected”。
Edit:
Looks like the trigger idea is a no go. I added the following to the control template of a test combo box to no avail:
Additionally, when trying to edit the control template in Blend (Edit Current) I am left with a featureless combobox, no colors, just an ugly button (but there is a borderless dropdown). Try someone elses suggestion (Mike Brown perhaps).
Original:
You can use a Trigger in the Control template. Here is an example using a ListBox from an app I am working on.
The above ControlTemplate has a Trigger which checks the Property HasItems. If False, a textblock saying "No Items" is displayed in the middle of the ListBox. If there are Items, they are displayed.
In your case change the trigger to check to see if ItemSelected is x:Null and set the Text property to "Nothing Selected".
我发现这里阻力最小的路径是使用 空对象模式在 .NET Framework 中使用此模式的示例,如果您为 Thingo 创建 Null 对象,请考虑静态值 Double.NaN,在视图模型中,您可以将其附加到列表的前面以表示“未选择任何内容”。为 Thingo 类创建一个 DataTemplate,该类具有用于显示“选择值”的 Null 对象实例的 DataTrigger。
我可以提供一个代码示例,但已经过了我的睡觉时间。
The path of least resistance here that I've found is to use the Null Object Pattern For an example of using this pattern in the .NET Framework, consider the static value Double.NaN if you create a Null Object for your Thingo, in your view model you can append it to the front of your list to signify "nothing is selected". Create a DataTemplate for the Thingo class that has a DataTrigger for the Null Object instance that shows "Select a Value".
I could give a code sample but it's past my bed time.
我知道这是一个旧线程,但这是我的做法。获取 Thingos 集合后,我只需插入一个具有虚假 ID 值和显示值“选择事物”的新 Thingo。
现在,当 ComboBox 进行数据绑定时,第一项是“选择一个事物”。然后,当选择 Thingo 时,我会测试 SelectedThingo 的 ID,并对其采取相应的操作。
I know this is an old thread, but here is how I do it. After I fetch the Thingos collection, I simply insert a new Thingo with a bogus ID value and a display value of "Select a thingo."
Now, when the ComboBox is databound, the first item is "Select a thingo." Then when a Thingo is selected, I test the ID of the SelectedThingo, and act on it accordingly.
我知道我正在恢复旧帖子,但这是我的谷歌搜索中出现的第一个帖子。
在 Visual Studio 中,您可以选择将“默认选择”设置为 0,而不是 -1,并且将第一个选择设置为默认文本。
I know I'm resurrecting an old post, but this was the first one that came up on my google search.
In Visual Studio, you can choose to set the Default Selection to 0, instead of -1, and just have your first selection be the default text.
另一种选择:
Another option: