当前位置:  开发笔记 > 编程语言 > 正文

为什么我不能在ComboBox中选择空值?

如何解决《为什么我不能在ComboBox中选择空值?》经验,为你挑选了4个好方法。

在WPF中,似乎无法从ComboBox中选择(使用鼠标)"null"值.编辑为了澄清,这是.NET 3.5 SP1.

这是一些显示我的意思的代码.首先,C#声明:

public class Foo
{
    public Bar Bar { get; set; }
}

public class Bar 
{
    public string Name { get; set; }
}

接下来,我的Window1 XAML:


    
        
    

最后,我的Window1类:

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();

        bars.ItemsSource = new ObservableCollection 
        {
            null, 
            new Bar { Name = "Hello" }, 
            new Bar { Name = "World" } 
        };
        this.DataContext = new Foo();
    }
}

与我一起?我有一个ComboBox,其项目绑定到Bar实例列表,其中一个为null.我已将窗口绑定到Foo的实例,并且ComboBox正在显示其Bar属性的值.

当我运行这个应用程序时,ComboBox以空显示开始,因为默认情况下Foo.Bar为null.没关系.如果我使用鼠标向下放下ComboBox并选择"Hello"项,那也可以.但是如果我尝试重新选择列表顶部的空项,ComboBox将关闭并返回其先前的"Hello"值!

使用箭头键选择空值按预期工作,并以编程方式设置它也可以.它只能用鼠标选择不起作用.

我知道一个简单的解决方法是让一个Bar的实例代表null并通过IValueConverter运行它,但有人可以解释为什么用鼠标选择null在WPF的ComboBox中不起作用?



1> Tim Erickson..:

键盘根本没有选择空"项目" - 而是取消选择前一项并且不能(可以)选择后续项目. 这就是为什么在用键盘"选择"空项后,你不能再重新选择之前选择的项目("你好") - 除了通过鼠标!

简而言之,您既不能选择也不能取消选择ComboBox中的空项.当您认为自己这样做时,您宁愿取消选择或选择上一个或新项目.

通过向ComboBox中的项添加背景,可以最好地看到这一点.当您选择"Hello"时,您会注意到ComboBox中的彩色背景,但是当您通过键盘取消选择时,背景颜色会消失.我们知道这不是null项,因为当我们通过鼠标向下放下列表时,null项实际上具有背景颜色!

从原始问题中修改的以下XAML将在项目后面放置一个LightBlue背景,以便您可以看到此行为.


    
        
            
                
                    
                        
                    
                
            
        
    

如果你想进一步验证,可以在ComboBox上处理SelectionChanged事件,看看"选择空项"实际上在SelectionChangedEventArgs中给出了一个空数组AddedItems,并且"用鼠标选择'Hello'取消选择空项"给出一个空数组的RemovedItems.



2> Andrew Mikha..:

好吧,我最近遇到了与ComboBox的null值相同的问题.我用两个转换器解决了这个问题:

    对于ItemsSource属性:它用转换器参数中传递的任何值替换集合中的值:

    class EnumerableNullReplaceConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var collection = (IEnumerable)value;
    
            return
                collection
                .Cast()
                .Select(x => x ?? parameter)
                .ToArray();
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
    

    对于SelectedValue属性:这个属性相同,但对于单个值和两种方式:

    class NullReplaceConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value ?? parameter;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value.Equals(parameter) ? null : value;
        }
    }
    

    使用示例:

    
    

    结果:

    在此输入图像描述

    注意:如果绑定到ObservableCollection,则会丢失更改通知.此外,您不希望集合中有多个值.



    3> 小智..:

    我为这个问题找到了一个新的解决方案."使用Mahapps"

      xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
    
    
      
    

    在此输入图像描述

    在此输入图像描述

    您可以使用关闭按钮清除内容.

    谢谢.



    4> Galghamon..:

    我知道这个答案不是你要求的(解释为什么它不适用于鼠标),但我认为这个前提是有缺陷的:

    从我作为程序员和用户(而不是.NET)的角度来看,选择空值是件坏事."null"应该是缺少值,而不是你选择的东西.

    如果您需要明确不选择某些内容的能力,我会建议您提到的解决方法(" - ","na"或"none"作为值)或更好

    使用可以取消选中的复选框包装组合框以禁用组合框.从用户的角度和编程方面来看,这是最干净的设计.


    我不相信这个解决方案.从用户的角度来看,为组合框中明确包含的内容添加额外的控件(作为空项,或标记为"(无)"的项目或其他内容),因此需要额外的点击并进一步复杂化输入表单,这可能被认为是糟糕的UI设计.在编程方面,`null`确实表示没有值,同时保持与实际属性类型的类型兼容,而不是任何占位符"none selected"-objects.
    推荐阅读
    农大军乐团_697
    这个屌丝很懒,什么也没留下!
    DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
    Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有