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

时间:2020-12-08 22:50:10

In WPF, it seems to be impossible to select (with the mouse) a "null" value from a ComboBox. Edit To clarify, this is .NET 3.5 SP1.

在WPF中,似乎不可能(用鼠标)从ComboBox中选择“null”值。编辑澄清,这是。net 3.5 SP1。

Here's some code to show what I mean. First, the C# declarations:

这里有一些代码来说明我的意思。首先,c#声明:

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

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

Next, my Window1 XAML:

接下来,我的Window1 XAML:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel>
        <ComboBox x:Name="bars" 
                  DisplayMemberPath="Name" 
                  Height="21" 
                  SelectedItem="{Binding Bar}"
                  />
    </StackPanel>
</Window>

And lastly, my Window1 class:

最后,我的windows1类:

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

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

With me? I have a ComboBox whose items are bound to a list of Bar instances, one of which is null. I have bound the window to an instance of Foo, and the ComboBox is displaying the value of its Bar property.

和我在一起吗?我有一个ComboBox,它的项被绑定到一个Bar实例列表,其中一个实例为null。我将窗口绑定到Foo实例,ComboBox显示其Bar属性的值。

When I run this app, the ComboBox starts with an empty display because Foo.Bar is null by default. That's fine. If I use the mouse to drop the ComboBox down and select the "Hello" item, that works too. But then if I try to re-select the empty item at the top of the list, the ComboBox closes and returns to its previous value of "Hello"!

当我运行这个应用程序时,ComboBox以一个空的显示开始,因为Foo。Bar默认为空。这很好。如果我使用鼠标来下拉ComboBox并选择“Hello”项,也可以。但是,如果我尝试重新选择列表顶部的空项,ComboBox将关闭并返回到之前的值“Hello”!

Selecting the null value with the arrow keys works as expected, and setting it programatically works too. It's only selecting with a mouse that doesn't work.

使用箭头键选择null值和预期的一样,并通过编程方式设置它。它只是用一个不能用的鼠标进行选择。

I know an easy workaround is to have an instance of Bar that represents null and run it through an IValueConverter, but can someone explain why selecting null with the mouse doesn't work in WPF's ComboBox?

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

10 个解决方案

#1


16  

The null "item" is not being selected by the keyboard at all - rather the previous item is being unselected and no subsequent item is (able to be) selected. This is why, after "selecting" the null item with the keyboard, you are thereafter unable to re-select the previously selected item ("Hello") - except via the mouse!

空“项目”根本不是由键盘选择的——而是前面的项目被取消选择,没有后续的项目被选中(可以被选中)。这就是为什么在用键盘“选择”空项后,您以后无法重新选择先前选中的项(“Hello”)——除了通过鼠标!

In short, you can neither select nor deselect a null item in a ComboBox. When you think you are doing so, you are rather deselecting or selecting the previous or a new item.

简而言之,您不能在组合框中选择或取消选中空项。当你认为你在这样做的时候,你是在取消选择或者选择之前的或者一个新的项目。

This can perhaps best be seen by adding a background to the items in the ComboBox. You will notice the colored background in the ComboBox when you select "Hello", but when you deselect it via the keyboard, the background color disappears. We know this is not the null item, because the null item actually has the background color when we drop the list down via the mouse!

这可以通过在ComboBox中添加一个背景来实现。当您选择“Hello”时,您将注意到ComboBox中的彩色背景,但是当您通过键盘取消选中它时,背景颜色将消失。我们知道这不是空项目,因为空项目实际上有背景颜色,当我们通过鼠标向下拖拽列表!

The following XAML, modified from that in the original question, will put a LightBlue background behind the items so you can see this behavior.

下面的XAML,在最初的问题中修改过,将在项目后面添加一个LightBlue背景,这样您就可以看到这种行为。

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel>
        <ComboBox x:Name="bars" Height="21" SelectedItem="{Binding Bar}">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <Grid Background="LightBlue" Width="200" Height="20">
                        <TextBlock Text="{Binding Name}" />
                    </Grid>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    </StackPanel>
</Window>

If you want further validation, you can handle the SelectionChanged event on the ComboBox and see that "selecting the null item" actually gives an empty array of AddedItems in its SelectionChangedEventArgs, and "deselecting the null item by selecting 'Hello' with the mouse" gives an empty array of RemovedItems.

如果您希望进行进一步的验证,您可以处理ComboBox上的SelectionChanged事件,并看到“选择空项”实际上会在其SelectionChangedEventArgs中给出一个addeditem的空数组,而“用鼠标选择‘Hello’取消选中空项”则会得到一个removeditem的空数组。

#2


10  

Well I recently ran into the same problem with null value for ComboBox. I've solved it by using two converters:

我最近遇到了ComboBox的空值问题。我用两个转换器解决了这个问题

  1. For ItemsSource property: it replaces null values in the collection by any value passed inside converter's parameter:

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

    class EnumerableNullReplaceConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var collection = (IEnumerable)value;
    
            return
                collection
                .Cast<object>()
                .Select(x => x ?? parameter)
                .ToArray();
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
    
  2. For SelectedValue property: this one does the same but for the single value and in two ways:

    对于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;
        }
    }
    

Example of use:

使用的例子:

<ComboBox 
    ItemsSource="{Binding MyValues, Converter={StaticResource EnumerableNullReplaceConverter}, ConverterParameter='(Empty)'}" 
    SelectedValue="{Binding SelectedMyValue, Converter={StaticResource NullReplaceConverter}, ConverterParameter='(Empty)'}"
    />

Result:

结果:

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

Note: If you bind to ObservableCollection then you will lose change notifications. Also you don't want to have more than one null value in the collection.

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

#3


4  

I know this answer isn't what you asked for (an explanation of why it doesn't work with the mouse), but I think the premise is flawed:

我知道这个答案不是你想要的(解释为什么它不能和鼠标一起工作),但我认为前提是有缺陷的:

From my perspective as a programmer and user (not .NET), selecting a null value is a bad thing. "null" is supposed to be the absence of a value, not something you select.

从我作为程序员和用户(不是。net)的角度来看,选择空值是件坏事。“null”应该是没有值的,而不是您选择的。

If you need the ability explicitly not to select something, I would suggest either the work-around you mentioned ("-", "n.a." or "none" as a value), or better

如果您需要明确地不选择某样东西的能力,我建议您所提到的工作(“-”、“n.a”或“none”作为值),或者更好

  • wrap the combobox with a checkbox that can be unchecked to disable the combobox. This strikes me as the cleanest design both from a user's perspective and programmatically.
  • 用复选框包装combobox,可以选中该复选框以禁用combobox。从用户的角度和编程上来说,这是最干净的设计。

#4


4  

I got a new solution for this question. "USING Mahapps"

我对这个问题有了新的解决办法。“使用Mahapps”

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


  <ComboBox x:Name="bars"  **controls:TextBoxHelper.ClearTextButton="True"**
              DisplayMemberPath="Name" 
              Height="21" 
              SelectedItem="{Binding Bar}"/>

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

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

You can use the close button to clear the content.

您可以使用close按钮来清除内容。

Thanks.

谢谢。

#5


1  

this might not address your answer completely, but hopefully its a hit in the right direction:

这可能不能完全解决你的问题,但希望这是一个正确的方向:

  1. Have you installed SP1?
  2. 你安装SP1吗?

From Scott Gu's Blog:

从斯科特顾的博客:

  • NET 3.5 SP1 includes several data binding and editing improvements to
    WPF. These include:
  • NET 3.5 SP1包含对WPF的一些数据绑定和编辑改进。这些包括:
  • StringFormat support within {{ Binding }} expressions to enable easy formatting of bound values
  • {{绑定}}表达式中的StringFormat支持使绑定值易于格式化
  • New alternating rows support within controls derived from ItemsControl, which makes it easier to set alternating properties on rows (for example: alternating background colors)
  • 由ItemsControl派生的控件中的新交替行支持,这使得在行上设置交替属性更容易(例如:交替背景颜色)
  • Better handling and conversion support for null values in editable controls Item-level validation that applies validation rules to an entire bound item
  • 更好地处理和转换支持可编辑的null值,可以控制项目级验证,将验证规则应用到整个绑定项。
  • MultiSelector support to handle multi-selection and bulk editing scenarios
  • 多选择器支持处理多选择和批量编辑场景
  • IEditableCollectionView support to interface data controls to data sources and enable editing/adding/removing items in a transactional way
  • IEditableCollectionView支持对数据源进行接口数据控制,并允许以事务性方式编辑/添加/删除项目。
  • Performance improvements when binding to IEnumerable data sources
  • 当绑定到IEnumerable数据源时,性能有所提高

Sorry if I wasted your time and this was not even close..but I think the problem is inherited from:

对不起,如果我浪费了你的时间,这甚至不是很接近。但是我认为这个问题是遗传的:

constraints of the strongly typed dataset

强类型数据集的约束

NullValueDataSet Explained here

NullValueDataSet解释这里

But now the SP1 for .Net 3.5 should have addressed this issue..

但是现在。net 3.5的SP1应该已经解决了这个问题。

#6


1  

I spent one day to find a solution about this problem of selecting a null value in combobox and finally, yeah finally I found a solution in an article written at this url:

我花了一天的时间来找到一个解决这个问题的方法,在combobox中选择一个空值,最后,我终于在这个url的文章中找到了一个解决方案:

http://remyblok.tweakblogs.net/blog/7237/wpf-combo-box-with-empty-item-using-net-4-dynamic-objects.html

http://remyblok.tweakblogs.net/blog/7237/wpf-combo-box-with-empty-item-using-net-4-dynamic-objects.html

public class ComboBoxEmptyItemConverter : IValueConverter 
{ 
/// <summary> 
/// this object is the empty item in the combobox. A dynamic object that 
/// returns null for all property request. 
/// </summary> 
private class EmptyItem : DynamicObject 
{ 
    public override bool TryGetMember(GetMemberBinder binder, out object result) 
    { 
        // just set the result to null and return true 
        result = null; 
        return true; 
    } 
} 

public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
{ 
    // assume that the value at least inherits from IEnumerable 
    // otherwise we cannot use it. 
    IEnumerable container = value as IEnumerable; 

    if (container != null) 
    { 
        // everything inherits from object, so we can safely create a generic IEnumerable 
        IEnumerable<object> genericContainer = container.OfType<object>(); 
        // create an array with a single EmptyItem object that serves to show en empty line 
        IEnumerable<object> emptyItem = new object[] { new EmptyItem() }; 
        // use Linq to concatenate the two enumerable 
        return emptyItem.Concat(genericContainer); 
    } 

    return value; 
} 

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
{ 
    throw new NotImplementedException(); 
} 

}

}

 <ComboBox ItemsSource="{Binding  TestObjectCollection, Converter={StaticResource ComboBoxEmptyItemConverter}}" 
      SelectedValue="{Binding SelectedID}" 
      SelectedValuePath="ID" 
      DisplayMemberPath="Name" />

#7


0  

Try Binding.FallbackValue

尝试Binding.FallbackValue

From 6 Things I Bet You Didn't Know About Data Binding in WPF

我敢打赌,在WPF中,你不知道数据绑定的6件事

#8


0  

I had the same kind of problem we did some work around like adding a value property to the collection item like this :

我遇到了同样的问题我们做了一些工作比如给集合项目添加一个value属性

 public class Bar

   {
      public string Name { get; set; }
      public Bar Value
      {
         get { return String.IsNullOrEmpty(Name) ?  null :  this; } // you can define here your criteria for being null
      }
   }

Then while adding items instead of null I use the same object :

然后在添加项目而不是null时,我使用相同的对象:

  comboBox1.ItemsSource=  new ObservableCollection<Bar> 
        {
            new Bar(),
            new Bar { Name = "Hello" }, 
            new Bar { Name = "World" } 
        };

And instead of selecteditem I bind it to selectedvalue :

而不是selecteditem,我将它绑定到selectedvalue:

<ComboBox Height="23" Margin="25,40,133,0" DisplayMemberPath="Name"
              SelectedValuePath="Value" 
              SelectedValue="{Binding Bar}"
              Name="comboBox1" VerticalAlignment="Top" />

I know It is not a complete solution, just one workaround I use

我知道这不是一个完整的解决方案,只是我使用的一个解决方案。

#9


0  

ComboBox needs a DataTemplate to display the item no matter how simple it is. DataTemplate works like this: get a value from instance.[path], e.g.

ComboBox需要一个DataTemplate来显示项目,无论它多么简单。DataTemplate的工作方式如下:从实例获取值。(路径)。

bar1.Car.Color

So it cannot get a value from

所以它不能从

null.Car.Color

It will throw a null reference exception. So, the null instance will not be displayed. But the the Color - if it is a reference type - is allowed to be null because there will be no exception in this case.

它将抛出一个空引用异常。因此,null实例将不会显示。但是颜色——如果是引用类型——被允许为null,因为在这种情况下没有例外。

#10


0  

Just a guess, but I think it sounds reasonable.

只是一个猜测,但我认为这听起来很合理。

Assume combobox is using "ListCollectionView" (lcv as its instance) as its item collection, which it should be. If you are a programmer, what you gonna do?

假设combobox使用“ListCollectionView”(lcv作为实例)作为其项目集合,应该是这样。如果你是一个程序员,你会怎么做?

I will respons to both Keyboard and Mouse.

我将响应键盘和鼠标。

Once I get Keyboard input, I use

一旦我得到键盘输入,我使用

lcv.MoveCurrentToNext();

or

lcv.MoveCurrentToPrevious();

So, sure keyboard works well.

所以,确保键盘运行良好。

Then I am working on respons Mouse inputs. And it comes the problem.

然后我正在研究响应鼠标输入。问题来了。

  1. I want to listen 'MouseClick' event of my item. But probably, my Item doesn't generated, it is just a placeholder. So when user click on this placeholder, I get nothing.

    我想听“MouseClick”事件我的项目。但是,我的项目可能不会生成,它只是一个占位符。所以当用户点击这个占位符时,我什么也得不到。

  2. If I get the event successfully, what's next. I will invoke

    如果我成功地得到了这个事件,接下来是什么?我将调用

    lcv.MoveCurrentTo(selectedItem);

    lcv.MoveCurrentTo(设置selectedItem);

the "selectedItem" which would be null is not an acceptable parameter here I think.

“selectedItem”将是空的,我认为这不是一个可接受的参数。

Anyway, it's just guessing. I don't have time to debug into it though I am able to. I have a bunch of defects to fix. Good Luck. :)

无论如何,这只是猜测。我没有时间去调试它,尽管我可以。我有一堆缺陷需要修复。祝你好运。:)

#1


16  

The null "item" is not being selected by the keyboard at all - rather the previous item is being unselected and no subsequent item is (able to be) selected. This is why, after "selecting" the null item with the keyboard, you are thereafter unable to re-select the previously selected item ("Hello") - except via the mouse!

空“项目”根本不是由键盘选择的——而是前面的项目被取消选择,没有后续的项目被选中(可以被选中)。这就是为什么在用键盘“选择”空项后,您以后无法重新选择先前选中的项(“Hello”)——除了通过鼠标!

In short, you can neither select nor deselect a null item in a ComboBox. When you think you are doing so, you are rather deselecting or selecting the previous or a new item.

简而言之,您不能在组合框中选择或取消选中空项。当你认为你在这样做的时候,你是在取消选择或者选择之前的或者一个新的项目。

This can perhaps best be seen by adding a background to the items in the ComboBox. You will notice the colored background in the ComboBox when you select "Hello", but when you deselect it via the keyboard, the background color disappears. We know this is not the null item, because the null item actually has the background color when we drop the list down via the mouse!

这可以通过在ComboBox中添加一个背景来实现。当您选择“Hello”时,您将注意到ComboBox中的彩色背景,但是当您通过键盘取消选中它时,背景颜色将消失。我们知道这不是空项目,因为空项目实际上有背景颜色,当我们通过鼠标向下拖拽列表!

The following XAML, modified from that in the original question, will put a LightBlue background behind the items so you can see this behavior.

下面的XAML,在最初的问题中修改过,将在项目后面添加一个LightBlue背景,这样您就可以看到这种行为。

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel>
        <ComboBox x:Name="bars" Height="21" SelectedItem="{Binding Bar}">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <Grid Background="LightBlue" Width="200" Height="20">
                        <TextBlock Text="{Binding Name}" />
                    </Grid>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    </StackPanel>
</Window>

If you want further validation, you can handle the SelectionChanged event on the ComboBox and see that "selecting the null item" actually gives an empty array of AddedItems in its SelectionChangedEventArgs, and "deselecting the null item by selecting 'Hello' with the mouse" gives an empty array of RemovedItems.

如果您希望进行进一步的验证,您可以处理ComboBox上的SelectionChanged事件,并看到“选择空项”实际上会在其SelectionChangedEventArgs中给出一个addeditem的空数组,而“用鼠标选择‘Hello’取消选中空项”则会得到一个removeditem的空数组。

#2


10  

Well I recently ran into the same problem with null value for ComboBox. I've solved it by using two converters:

我最近遇到了ComboBox的空值问题。我用两个转换器解决了这个问题

  1. For ItemsSource property: it replaces null values in the collection by any value passed inside converter's parameter:

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

    class EnumerableNullReplaceConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var collection = (IEnumerable)value;
    
            return
                collection
                .Cast<object>()
                .Select(x => x ?? parameter)
                .ToArray();
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
    
  2. For SelectedValue property: this one does the same but for the single value and in two ways:

    对于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;
        }
    }
    

Example of use:

使用的例子:

<ComboBox 
    ItemsSource="{Binding MyValues, Converter={StaticResource EnumerableNullReplaceConverter}, ConverterParameter='(Empty)'}" 
    SelectedValue="{Binding SelectedMyValue, Converter={StaticResource NullReplaceConverter}, ConverterParameter='(Empty)'}"
    />

Result:

结果:

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

Note: If you bind to ObservableCollection then you will lose change notifications. Also you don't want to have more than one null value in the collection.

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

#3


4  

I know this answer isn't what you asked for (an explanation of why it doesn't work with the mouse), but I think the premise is flawed:

我知道这个答案不是你想要的(解释为什么它不能和鼠标一起工作),但我认为前提是有缺陷的:

From my perspective as a programmer and user (not .NET), selecting a null value is a bad thing. "null" is supposed to be the absence of a value, not something you select.

从我作为程序员和用户(不是。net)的角度来看,选择空值是件坏事。“null”应该是没有值的,而不是您选择的。

If you need the ability explicitly not to select something, I would suggest either the work-around you mentioned ("-", "n.a." or "none" as a value), or better

如果您需要明确地不选择某样东西的能力,我建议您所提到的工作(“-”、“n.a”或“none”作为值),或者更好

  • wrap the combobox with a checkbox that can be unchecked to disable the combobox. This strikes me as the cleanest design both from a user's perspective and programmatically.
  • 用复选框包装combobox,可以选中该复选框以禁用combobox。从用户的角度和编程上来说,这是最干净的设计。

#4


4  

I got a new solution for this question. "USING Mahapps"

我对这个问题有了新的解决办法。“使用Mahapps”

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


  <ComboBox x:Name="bars"  **controls:TextBoxHelper.ClearTextButton="True"**
              DisplayMemberPath="Name" 
              Height="21" 
              SelectedItem="{Binding Bar}"/>

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

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

You can use the close button to clear the content.

您可以使用close按钮来清除内容。

Thanks.

谢谢。

#5


1  

this might not address your answer completely, but hopefully its a hit in the right direction:

这可能不能完全解决你的问题,但希望这是一个正确的方向:

  1. Have you installed SP1?
  2. 你安装SP1吗?

From Scott Gu's Blog:

从斯科特顾的博客:

  • NET 3.5 SP1 includes several data binding and editing improvements to
    WPF. These include:
  • NET 3.5 SP1包含对WPF的一些数据绑定和编辑改进。这些包括:
  • StringFormat support within {{ Binding }} expressions to enable easy formatting of bound values
  • {{绑定}}表达式中的StringFormat支持使绑定值易于格式化
  • New alternating rows support within controls derived from ItemsControl, which makes it easier to set alternating properties on rows (for example: alternating background colors)
  • 由ItemsControl派生的控件中的新交替行支持,这使得在行上设置交替属性更容易(例如:交替背景颜色)
  • Better handling and conversion support for null values in editable controls Item-level validation that applies validation rules to an entire bound item
  • 更好地处理和转换支持可编辑的null值,可以控制项目级验证,将验证规则应用到整个绑定项。
  • MultiSelector support to handle multi-selection and bulk editing scenarios
  • 多选择器支持处理多选择和批量编辑场景
  • IEditableCollectionView support to interface data controls to data sources and enable editing/adding/removing items in a transactional way
  • IEditableCollectionView支持对数据源进行接口数据控制,并允许以事务性方式编辑/添加/删除项目。
  • Performance improvements when binding to IEnumerable data sources
  • 当绑定到IEnumerable数据源时,性能有所提高

Sorry if I wasted your time and this was not even close..but I think the problem is inherited from:

对不起,如果我浪费了你的时间,这甚至不是很接近。但是我认为这个问题是遗传的:

constraints of the strongly typed dataset

强类型数据集的约束

NullValueDataSet Explained here

NullValueDataSet解释这里

But now the SP1 for .Net 3.5 should have addressed this issue..

但是现在。net 3.5的SP1应该已经解决了这个问题。

#6


1  

I spent one day to find a solution about this problem of selecting a null value in combobox and finally, yeah finally I found a solution in an article written at this url:

我花了一天的时间来找到一个解决这个问题的方法,在combobox中选择一个空值,最后,我终于在这个url的文章中找到了一个解决方案:

http://remyblok.tweakblogs.net/blog/7237/wpf-combo-box-with-empty-item-using-net-4-dynamic-objects.html

http://remyblok.tweakblogs.net/blog/7237/wpf-combo-box-with-empty-item-using-net-4-dynamic-objects.html

public class ComboBoxEmptyItemConverter : IValueConverter 
{ 
/// <summary> 
/// this object is the empty item in the combobox. A dynamic object that 
/// returns null for all property request. 
/// </summary> 
private class EmptyItem : DynamicObject 
{ 
    public override bool TryGetMember(GetMemberBinder binder, out object result) 
    { 
        // just set the result to null and return true 
        result = null; 
        return true; 
    } 
} 

public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
{ 
    // assume that the value at least inherits from IEnumerable 
    // otherwise we cannot use it. 
    IEnumerable container = value as IEnumerable; 

    if (container != null) 
    { 
        // everything inherits from object, so we can safely create a generic IEnumerable 
        IEnumerable<object> genericContainer = container.OfType<object>(); 
        // create an array with a single EmptyItem object that serves to show en empty line 
        IEnumerable<object> emptyItem = new object[] { new EmptyItem() }; 
        // use Linq to concatenate the two enumerable 
        return emptyItem.Concat(genericContainer); 
    } 

    return value; 
} 

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
{ 
    throw new NotImplementedException(); 
} 

}

}

 <ComboBox ItemsSource="{Binding  TestObjectCollection, Converter={StaticResource ComboBoxEmptyItemConverter}}" 
      SelectedValue="{Binding SelectedID}" 
      SelectedValuePath="ID" 
      DisplayMemberPath="Name" />

#7


0  

Try Binding.FallbackValue

尝试Binding.FallbackValue

From 6 Things I Bet You Didn't Know About Data Binding in WPF

我敢打赌,在WPF中,你不知道数据绑定的6件事

#8


0  

I had the same kind of problem we did some work around like adding a value property to the collection item like this :

我遇到了同样的问题我们做了一些工作比如给集合项目添加一个value属性

 public class Bar

   {
      public string Name { get; set; }
      public Bar Value
      {
         get { return String.IsNullOrEmpty(Name) ?  null :  this; } // you can define here your criteria for being null
      }
   }

Then while adding items instead of null I use the same object :

然后在添加项目而不是null时,我使用相同的对象:

  comboBox1.ItemsSource=  new ObservableCollection<Bar> 
        {
            new Bar(),
            new Bar { Name = "Hello" }, 
            new Bar { Name = "World" } 
        };

And instead of selecteditem I bind it to selectedvalue :

而不是selecteditem,我将它绑定到selectedvalue:

<ComboBox Height="23" Margin="25,40,133,0" DisplayMemberPath="Name"
              SelectedValuePath="Value" 
              SelectedValue="{Binding Bar}"
              Name="comboBox1" VerticalAlignment="Top" />

I know It is not a complete solution, just one workaround I use

我知道这不是一个完整的解决方案,只是我使用的一个解决方案。

#9


0  

ComboBox needs a DataTemplate to display the item no matter how simple it is. DataTemplate works like this: get a value from instance.[path], e.g.

ComboBox需要一个DataTemplate来显示项目,无论它多么简单。DataTemplate的工作方式如下:从实例获取值。(路径)。

bar1.Car.Color

So it cannot get a value from

所以它不能从

null.Car.Color

It will throw a null reference exception. So, the null instance will not be displayed. But the the Color - if it is a reference type - is allowed to be null because there will be no exception in this case.

它将抛出一个空引用异常。因此,null实例将不会显示。但是颜色——如果是引用类型——被允许为null,因为在这种情况下没有例外。

#10


0  

Just a guess, but I think it sounds reasonable.

只是一个猜测,但我认为这听起来很合理。

Assume combobox is using "ListCollectionView" (lcv as its instance) as its item collection, which it should be. If you are a programmer, what you gonna do?

假设combobox使用“ListCollectionView”(lcv作为实例)作为其项目集合,应该是这样。如果你是一个程序员,你会怎么做?

I will respons to both Keyboard and Mouse.

我将响应键盘和鼠标。

Once I get Keyboard input, I use

一旦我得到键盘输入,我使用

lcv.MoveCurrentToNext();

or

lcv.MoveCurrentToPrevious();

So, sure keyboard works well.

所以,确保键盘运行良好。

Then I am working on respons Mouse inputs. And it comes the problem.

然后我正在研究响应鼠标输入。问题来了。

  1. I want to listen 'MouseClick' event of my item. But probably, my Item doesn't generated, it is just a placeholder. So when user click on this placeholder, I get nothing.

    我想听“MouseClick”事件我的项目。但是,我的项目可能不会生成,它只是一个占位符。所以当用户点击这个占位符时,我什么也得不到。

  2. If I get the event successfully, what's next. I will invoke

    如果我成功地得到了这个事件,接下来是什么?我将调用

    lcv.MoveCurrentTo(selectedItem);

    lcv.MoveCurrentTo(设置selectedItem);

the "selectedItem" which would be null is not an acceptable parameter here I think.

“selectedItem”将是空的,我认为这不是一个可接受的参数。

Anyway, it's just guessing. I don't have time to debug into it though I am able to. I have a bunch of defects to fix. Good Luck. :)

无论如何,这只是猜测。我没有时间去调试它,尽管我可以。我有一堆缺陷需要修复。祝你好运。:)