WPF MVVM Editable Combobox新值为null

时间:2013-04-09 20:49:09

标签: c# wpf mvvm combobox

在这里尝试了类似问题的所有解决方案,但仍然没有。我有一个ComboBox,可用于选择现有项目和/或添加新项目。只有选定的项目部分有效。类别只是一个NameId的对象。

提前致谢!

XAML

<ComboBox Name="CbCategory" ItemsSource="{Binding Categories}"
    SelectedItem="{Binding SelectedCategory.Name, UpdateSourceTrigger=PropertyChanged}"
    Text="{Binding NewCategory.Name}" DisplayMemberPath="Name" 
    IsEditable="True"/>

Code behind

private Category _selectedCategory;

public Category SelectedCategory
{
    get { return _selectedCategory; }

    set
    {
        if (Equals(_selectedCategory, value)) return;
        _selectedCategory = value;
        SendPropertyChanged("SelectedCategory");
    }
}

private Category _newCategory;

public Category NewCategory
{
    get { return _newCategory; }

    set
    {
         if (Equals(_newCategory, value)) return;
         _newCategory = value;
          SendPropertyChanged("NewCategory");
    }
}   

2 个答案:

答案 0 :(得分:1)

您的Text绑定不起作用,因为您绑定了null Category属性。改为实例化。

public Category NewCategory
{
    get { return _newCategory ?? (_newCategory = new Category()); }
    set
        {
          if (Equals(_newCategory, value)) return;
          _newCategory = value;
           SendPropertyChanged("NewCategory");
         }
}

编辑:根据您的评论进行阐述:

您的ComboBox.Text绑定设置为"{Binding NewCategory.Name}",因此无论SelectedCategory的值是多少,Text属性都将始终反映{{1}的名称}}。

NewCategory为null时,NewCategory属性无法绑定,因此无法执行双向绑定(即Text属性的值不能被传递回Text,因为这会导致NewCategory.Name(因为NullReferenceException为空)。

这不会影响NewCategory的情况,因为它直接绑定到SelectedItem属性,而不是它的子属性。

答案 1 :(得分:0)

创建新变量以保留组合框的文本。如果selectedItem具有null值,则将组合框的文本作为新项,

代码:

<ComboBox Name="CbCategory" ItemsSource="{Binding Categories}"
    SelectedItem="{Binding SelectedCategory.Name, UpdateSourceTrigger=PropertyChanged}"
    Text="{Binding Name}" DisplayMemberPath="Name" 
    IsEditable="True"/>

private String _name;
public Category Name
{
    get { return _name; }

    set
    {        
         _name = value
         SendPropertyChanged("Name");
    }
}

public ICommand ItemChange
{
 get
 {
   `return new RelayCommand(() =>`{
                    try{string item = this.SelectedCategory.Code;}
catch(Exception ex){string item = this.Name;}
                }, () => { return true; });
            }
        }