【问题标题】:Search in listbox with wpf使用 wpf 在列表框中搜索
【发布时间】:2011-08-03 00:52:17
【问题描述】:

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

 <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>

我已经尝试了很多东西。但我只想保留一个简单的东西:一个文本框,如果你在那里填写一些字母,程序必须过滤这个字母组合存在的位置。知道简单解决方案或示例的人吗?

谢谢!

【问题讨论】:

    标签: c# wpf search listbox


    【解决方案1】:

    这是我制作的一个自定义控件,您可以使用它过滤封装任何类型对象的任何类型集合的任何 ItemsControl。这比保持代码干净要好:它完全符合 XAML decalrative 和“绑定”标准;)

    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 条消息。有机会在其他地方托管吗?
    【解决方案2】:

    您也可以在 ViewModel 中执行此操作。

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

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

    在您的视图模型中,设置您的属性和您的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); .....) 放在我的视图模型的构造函数中?
    • 是的,需要放在构造函数中。
    【解决方案3】:

    请看CollectionViewSource

    1) 创建一个 CollectionViewSource:

    private readonly CollectionViewSource viewSource = new CollectionViewSource();
    

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

    viewSource.Source = list;
    

    3) 在您的 ListView 上设置您的视源。

    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) 最后将 viewSource 的 refresh 方法放在过滤器 TextBox 的 TextChanged 上:

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

    希望这会有所帮助!

    【讨论】:

    • 但这就是我想的全部代码?我正在努力保持我的代码干净并与 MVVM 一起工作。关于如何做到这一点的想法?
    • @Ruben,请查看我的回答,了解如何在您的虚拟机中执行此操作。
    • 任何一种方式都可以。这里的关键是CollectionViewSource,可以创建它,也可以使用默认值。
    • 是的。 CollectionViewSource 非常适合过滤、排序等,而不必弄乱底层集合。
    猜你喜欢
    • 1970-01-01
    • 2017-10-04
    • 2010-10-16
    • 1970-01-01
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    • 2013-11-08
    • 2021-11-17
    相关资源
    最近更新 更多