通过文本框从列表框中过滤元素
您已经创建了一个绑定到机器列表的列表框。由于机器数量可能急剧增加,我需要按名称过滤。出于这个原因,我提供了一个TextBox,用户可以引入一个字符串来过滤掉。 我想创建另一个列表,它将绑定到视图,即第二个列表仅用于可视化。但是,我认为必须有一个更干净的方式来做到这一点。通过文本框从列表框中过滤元素
<ListBox IsSynchronizedWithCurrentItem="True" Visibility="{Binding MachinesPanelVisibility}"
ItemsSource="{Binding MachineRulesList}" SelectedIndex="{Binding ItemSelectionIndex}" />
<TextBox HorizontalAlignment="Right" Width="162" Text="Filter..." TextWrapping="Wrap" Margin="0,44,18,13" />
在视图模型:
public class BusinessRulesWizardViewModel : INotifyPropertyChanged
{
public ObservableCollection<string> MachineRulesList
{
get { return _machineRulesList; }
set
{
_machineRulesList = value;
OnPropertyChanged("MachineRulesList");
}
}
public BusinessRulesWizardViewModel(ISystemView systemViewManager,
IEventAggregator eventAggregator)
{
_machineRulesList = new ObservableCollection<string>();
_systemViewManager.GetMachines(page, pageSize).ToList().ForEach(
item => _machineRulesList.Add(item)
);
}
使用可以使用ICollectionView接口与Filter
属性设置为使用在TextBox
输入的文本谓词来包装你的收藏。这里有一个例子:
<ListBox IsSynchronizedWithCurrentItem="True" Visibility="{Binding MachinesPanelVisibility}"
ItemsSource="{Binding MachineRulesListView}"
SelectedIndex="{Binding ItemSelectionIndex}" />
<TextBox HorizontalAlignment="Right" Width="162"
Text="{Binding FilterText}"
TextWrapping="Wrap" Margin="0,44,18,13" />
-
public class BusinessRulesWizardViewModel : INotifyPropertyChanged
{
public ObservableCollection<string> MachineRulesList
{
get { return _machineRulesList; }
set
{
_machineRulesList = value;
OnPropertyChanged("MachineRulesList");
}
}
public string FilterText
{
get { return _filterText; }
set
{
_filterText= value;
OnPropertyChanged("FilterText");
MachineRulesListView.Refresh();
}
}
public ICollectionView MachineRulesListView { get; private set; }
public BusinessRulesWizardViewModel(ISystemView systemViewManager, IEventAggregator eventAggregator)
{
_machineRulesList = new ObservableCollection<string>();
MachineRulesListView = CollectionViewSource.GetDefaultView(_machineRulesList);
MachineRulesListView.Filter = new Predicate<object>(r => ((string)r).Contains(FilterText));
_systemViewManager.GetMachines(page, pageSize).ToList().ForEach(
item => _machineRulesList.Add(item)
);
}
}
我有一个比较器错误,说System.ComponentModel.IcollectionView不包含'更新'的定义。任何想法为什么? – Manolete
@Manolete - 哦,对不起,它应该是'Refresh',而不是'Update'。更正了答案。 –
我得到的另一个问题是MachineRulesListView.Filter = new Predicate
您是否尝试过使用[CollectionViews](http://msdn.microsoft.com/en-us/library/system.windows.data.collectionview .aspx)进行过滤?不幸的是,这可能会很慢,因为每次必须重新创建整个视图,这取决于您的项目数量,这可能会变慢。另一个值得关注的是[AutoCompletionTextBox](http://www.codeproject.com/KB/WPF/autocomplete%5Ftextbox.aspx),它非常好,因为它可以异步工作。 – dowhilefor
请在您的问题中正确格式化您的代码 –
Daniel,我无法做到这一点... – Manolete