我有一个ComboBox和ComboBox.IsEditable属性设置为True,以使ComboBox同时充当TextBox和下拉列表。但是当ComboBox受数据绑定时,输入自定义文本不会导致将新项目添加到数据绑定集合中。
例如,如果我在ComboBox中输入'Joe',该ComboBox绑定到人员列表(不包含值'Joe'),则不会将值'Joe'添加到drop中 - 自动下载列表。
处理此问题的最佳方法是什么?
答案 0 :(得分:77)
以下是获得所需行为的基本MVVM
合规方式:
MainWindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<ComboBox Margin="30,5,30,5"
IsEditable="True"
ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem}"
Text="{Binding NewItem, UpdateSourceTrigger=LostFocus}"/>
<TextBox Margin="30,5,30,5" />
</StackPanel>
</Window>
MainWindow.cs
public partial class MainWindow : Window, INotifyPropertyChanged
{
private string _selectedItem;
private ObservableCollection<string> _items = new ObservableCollection<string>()
{
"One",
"Two",
"Three",
"Four",
"Five",
};
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
}
public IEnumerable Items
{
get { return _items; }
}
public string SelectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
OnPropertyChanged("SelectedItem");
}
}
public string NewItem
{
set
{
if (SelectedItem != null)
{
return;
}
if (!string.IsNullOrEmpty(value))
{
_items.Add(value);
SelectedItem = value;
}
}
}
protected void OnPropertyChanged(string propertyName)
{
var handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
我必须在窗口中放置另一个控件,因为我已将UpdateSourceTrigger
绑定的Text
属性设置为LostFocus
。如果窗口中没有其他控件,则Combobox
永远不会失去焦点。
我更改了更新模式,因为默认的更新模式是Propertychanged
,它会为每次击键添加一个新项目。
E.G。如果您输入了文本“Window”,则会将以下内容添加到您的集合中:
W
Wi
Win
Wind
Windo
Window
答案 1 :(得分:4)
我会在LostFocus事件中处理它。
在这里,您可以检查SelectedItem是否为空。如果是这样,请将Text的值添加到绑定列表,并将SelectedItem设置为新项。
在XAML中:
<ComboBox Name="_list" LostFocus="LostFocus" IsEditable="True"/>
在代码隐藏中:
private ObservableCollection<string> _names;
public MainWindow()
{
InitializeComponent();
_names = new ObservableCollection<string> {"Eric", "Phillip"};
_list.SetBinding(ItemsControl.ItemsSourceProperty, new Binding {Source = _names});
}
private void LostFocus(object sender, RoutedEventArgs e)
{
var comboBox = (ComboBox) sender;
if(comboBox.SelectedItem != null)
return;
var newItem = comboBox.Text;
_names.Add(newItem);
comboBox.SelectedItem = newItem;
}
希望这会有所帮助:)
答案 2 :(得分:3)
我的建议是使用MVVM方法并将ComboBox.Text绑定到ViewModel的某些TextProperty。 (只需在视图中添加字符串属性即可实现) 然后,您可以处理此属性的setter中的输入,并将该新项添加到列表中,无论它在视图中“提交”的方式。 AFAIK没有开箱即用的机制来向您的数据源添加新项目,您无论如何都必须自己完成项目生成。
或者,您可以绑定--SelectedItem和ComboBox的文本 - 以避免在用户输入已知项目时进行查找。但回答你的问题可能不那么重要了。