【发布时间】:2013-05-24 10:04:39
【问题描述】:
我绑定了一个ObservableCollection 和一个ComboBox。我想要实现的是过滤 ObservableCollection 并且只让 ComboBox 显示过滤后的项目。后来某处我有一个foreach (item in ComboBox) loop。过滤应该是写一些字母,如果ObservableCollection中的项目的名称属性不包含该字母,则删除该项目。
我知道有一种方法可以使用 IsEditable 属性直接在 ComboBox 中输入,但对于这个示例,我们只使用一个额外的 TextBox 来供用户输入。
为了练习,我使用 ObservableCollection<string>(而不是拥有更多属性的 <myClass>。)
public MainWindow()
{
InitializeComponent();
names= new ObservableCollection<string>();
names.Add("Harry");
names.Add("Ron");
names.Add("Einstein");
names.Add("Frodo");
names.Add("Spiderman");
myComboBox.DataContext = this;
}
public ObservableCollection<string> names{ get; set; }
public ObservableCollection<string> filteredNames{ get; set; }
我已经创建了这个方法:
void toFilter()
{
filteredNames=new ObservableCollection<string>(names.Where(name=> name.StartsWith(myTextBox.Text)));
}
而在text changed:
private void myTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (myTextBox.Text.Length > 0)
{
toFilter();
}
myComboBox.DataContext = this; //Obviously doesn't work
}
所以我想保持原始集合完整(names),并在文本框中输入内容时显示filteredNames。我是否应该将组合框直接绑定到filteredNames(最初等于names),然后通过循环每次myTextBox_TextChanged 时与文本框输入不匹配的名称来删除?
其他方法是在将输入内容从names 更改为filteredNames 时更改组合框的绑定。
如何以简单的方式实现这一点?
编辑:
感谢使用 CollectionViewSource 的建议,它在此示例中运行良好,但在我的实际程序中我遇到了一些问题。我已将问题部分减少到此(来自 XAML Lover 解决方案)
view.Filter = delegate(object o)
{
if (o.ToString().StartsWith(myTextBox.Text))
{
return true;
}
return false;
};
我看到了下一个行为: 如果我什么都不写,一旦加载文件,comboBox 就会填充数据并且一切正常。如果我写了与“Unico.Canal”不同的任何东西,所有数据都会从组合框中消失(Unico 是我的命名空间,Canal 是 CollectionViewSource 的类),我已经通过反复试验意识到这一点。 代码有点乱(而且很长),因为我在那里有读取文件方法,你有没有看到可能给我这个错误的东西?我想我没有把代码放在正确的地方。有人可以解释一下那个“代表”到底在做什么以及它是如何工作的吗?
【问题讨论】:
标签: c# wpf binding filter combobox