通过文本框从列表框中过滤元素

问题描述:

您已经创建了一个绑定到机器列表的列表框。由于机器数量可能急剧增加,我需要按名称过滤。出于这个原因,我提供了一个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) 
     ); 
    } 
+0

您是否尝试过使用[CollectionViews](http://msdn.microsoft.com/en-us/library/system.windows.data.collectionview .aspx)进行过滤?不幸的是,这可能会很慢,因为每次必须重新创建整个视图,这取决于您的项目数量,这可能会变慢。另一个值得关注的是[AutoCompletionTextBox](http://www.codeproject.com/KB/WPF/autocomplete%5Ftextbox.aspx),它非常好,因为它可以异步工作。 – dowhilefor

+0

请在您的问题中正确格式化您的代码 –

+0

Daniel,我无法做到这一点... – Manolete

使用可以使用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) 
     ); 
    } 
} 
+0

我有一个比较器错误,说System.ComponentModel.IcollectionView不包含'更新'的定义。任何想法为什么? – Manolete

+0

@Manolete - 哦,对不起,它应该是'Refresh',而不是'Update'。更正了答案。 –

+0

我得到的另一个问题是MachineRulesListView.Filter = new Predicate (r => r.Contains(FilterText))不喜欢它。它抱怨,因为不能将谓词转换为谓词。如果我把它,它编译,但它给运行时错误... – Manolete