WPF中的列表框搜索

3

我有一个ListView,绑定了一个对象的可观察集合。这里的对象是“问题”。我想实现一种搜索引擎,在文本框或其他地方。但我有3个列。1个描述,1个短名称和1个问题类型。这是我的ListView代码:

 <ListView IsTextSearchEnabled="True"  TextSearch.TextPath="Description" ScrollViewer.CanContentScroll="True" SelectedItem="{Binding Path=SelectedQuestionDragList, UpdateSourceTrigger=PropertyChanged,Mode=OneWayToSource}" dd:DragDrop.IsDragSource="True" 
  dd:DragDrop.IsDropTarget="False"  Margin="0,34,393,333" Background="#CDC5CBC5" ScrollViewer.VerticalScrollBarVisibility="Visible"
                 dd:DragDrop.DropHandler="{Binding}" Name="listbox1" Height="155"  ItemsSource="{Binding AvailableQuestions}" SelectionChanged="listbox1_SelectionChanged">
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                        <GridViewColumn Header="Verkorte naam" Width="Auto" DisplayMemberBinding="{Binding Path=ShortName}" />
                        <GridViewColumn Header="Omschrijving" Width="Auto" DisplayMemberBinding="{Binding Path=Description}" />
                        <GridViewColumn Header="Type" Width="Auto" DisplayMemberBinding="{Binding Path=Type}" />
                    </GridView.Columns>
                </GridView>
            </ListView.View>
        </ListView>

我已经尝试了很多方法,但我只想保留一个简单的东西:一个文本框。如果你在里面输入一些字母,程序就会过滤出这些字母组合存在的地方。有没有人知道一个简单的解决方案或示例呢?

谢谢!

3个回答

5
Please take a look at CollectionViewSource 1) 创建一个CollectionViewSource:
private readonly CollectionViewSource viewSource = new CollectionViewSource();

2) 将您的列表设置为源:

viewSource.Source = list;

3) 将您的ListView视图设置为viewsource。

4) 当您完成此操作后,可以使用Filter属性:

viewSource.Filter = FilterResults;


private bool FilterResults(object obj)
{
    //match items here with your TextBox value.. obj is an item from the list    
}

5) 最后,在筛选文本框的TextChanged事件中使用viewSource的刷新方法:

 void TextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
    viewSource.Refresh();
}

希望这可以帮到您!

但这一切都在代码后面吧?我试图保持我的代码后面干净,并且与MVVM一起工作.. 有什么好的想法吗? - Ruben
@Ruben,请查看我的答案,了解如何在你的虚拟机中完成这个操作。 - Robaticus
无论哪种方式都可以..这里的关键是“CollectionViewSource”,可以创建它,也可以使用默认值。 - Arcturus
1
CollectionViewSource非常棒,可以进行过滤、排序等操作,而无需干扰底层集合。 - Robaticus

3

您也可以在ViewModel中完成此操作。

首先,将TextBox绑定到视图模型中的属性。请确保在XAML中将UpdateSourceTrigger设置为PropertyChanged,以便在每次按键时获取更新。

Text="{Binding Filter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

在您的ViewModel中,设置您的属性和CollectionView

    ICollectionView ViewFilter;


    private string _Filter;

    public string Filter
    {
        get { return _Filter; }
        set
        {
            _Filter = value;
            RaisePropertyChanged("Filter");
        }
    }

在构造函数中,连接视图并监视propertychanged事件:
        ViewFilter = CollectionViewSource.GetDefaultView(AvailableQuestion);

        ViewFilter.Filter = delegate(object item)
        {
            AvailableQuestion q = item as AvailableQuestion;
            // Check the value and return true, if it should be in the list
            // false if it should be exclucdd.

        };


        this.PropertyChanged += ((src, evt) =>
        {
            switch(evt.PropertyName)
            {
                case "Filter":
                    ProjectFilter.Refresh();
                    break;
            }

那么我必须将第二部分(ViewFilter = CollectionViewSource.GetDefaultView(AvailableQuestion);......)放在我的视图模型构造函数中吗? - Ruben
是的,那需要放在构造函数中。 - Robaticus

1
这是我制作的自定义控件,可以对包装任何类型对象集合的任何 ItemsControls 进行筛选。相比于保持代码干净,它更好:它完全符合 XAML 声明和“绑定”规范。;)

http://dotnetexplorer.blog.com/2011/04/07/wpf-itemscontrol-generic-staticreal-time-filter-custom-control-presentation/

你可以在示例中找到代码源(更多的帖子将深入了解组件)

优点是您无需关心集合视图管理,因此不会将 UI 问题强加给您的 vewmodel(因为必须面对真相:即使在视图模型中完成,过滤集合主要是 UI 问题,因此最好不要放在 VM 中)。至少将该逻辑放在行为中 ;)

这是你唯一需要拥有的东西,在列表框/列表视图上使用工作过滤器:

<SmartSearch:SmartSearchRoot x:Name="ss2"    Margin=" 10,0,10,0" >
  <SmartSearch:SmartSearchScope DataControl="{Binding ElementName=YOUR_LISTVIEW_NAME}"  UnderlyingType="{x:Type YOUR_NAMESPACE:YOUR_OBJECT_TYPE}">
     <!-- The list of property on which you want to apply filter -->                    
     <SmartSearch:PropertyFilter FieldName="YOUR_PROPERTY_ONE"  />
     <SmartSearch:PropertyFilter FieldName="YOUR_PROPERTY_TWO" MonitorPropertyChanged=""true"  />
  </SmartSearch:SmartSearchScope>
</SmartSearch:SmartSearchRoot>

我知道这是相当久以前的事了 - 但链接现在返回一个500消息。有没有可能它托管在其他地方? - Webbarr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接