【问题标题】:Filter / Search binded Listbox过滤/搜索绑定列表框
【发布时间】:2015-07-04 14:47:19
【问题描述】:

嘿嘿,

我有一个绑定到 ObservableCollection 的 ListBox,现在我正在尝试实现 Search / Filter 功能。但它不工作......尝试了一切:(

这是我的列表框的图片http://i.imgur.com/el8KF3T.png

感谢 Maximus 的链接,我得到了解决方案。我更新了我的代码。

这是我迄今为止尝试的 .xaml 代码

 <ListBox Name="lstWarning" Margin="-14,3,-31,-30">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Canvas Height="62" Width="582">
                <Label Foreground="#FFA8A4A4" FontFamily="{DynamicResource HeaderFontFamily}" FontSize="11" Content="{Binding DirName}" Canvas.Left="39" Canvas.Top="23"/>
                <Label Foreground="#FFA8A4A4" FontFamily="{DynamicResource HeaderFontFamily}" FontSize="11" Content="{Binding CreationDate}" Canvas.Left="39" Canvas.Top="40"/>
                <Label Foreground="White" FontFamily="{DynamicResource HeaderFontFamily}" FontSize="14" Content="{Binding FileName}" Canvas.Left="39" Canvas.Top="4"/>
                <Label Foreground="#FFA8A4A4" FontFamily="{DynamicResource HeaderFontFamily}" FontSize="11" Content="{Binding Extension}" Canvas.Left="224" Canvas.Top="40"/>
                <Label Foreground="#FFA8A4A4" FontFamily="{DynamicResource HeaderFontFamily}" FontSize="11" Content="{Binding FileSize}" Canvas.Left="155" Canvas.Top="40"/>
                <Image Source="{Binding StatusImage}" Width="30" Height="30" Canvas.Left="10" Canvas.Top="6" Stretch="Fill"/>
            </Canvas>
        </DataTemplate>
    </ListBox.ItemTemplate>
 </ListBox>

如果在 TextChanged 事件中完成,会发生什么

private void cmdSearchWarnings_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e) {

        CollectionView cv = (CollectionView)CollectionViewSource.GetDefaultView(lstWarning.ItemsSource);
        if (!string.IsNullOrEmpty(txtSearchWarnings.Text)) {


            if (isFilter) {
                cv.Filter = null;
                isFilter = false;   
            }
            else {
                cv.Filter = new Predicate<object>(FilterByFileName);
                isFilter = true;
            }
        }
        else {
            cv.Filter = null;
            isFilter = false;
        }
    }

    private bool FilterByFileName(object _warningObj) {
        if (_warningList != null) {

            if (!string.IsNullOrEmpty(txtSearchWarnings.Text)) {
                var warning = _warningObj as WarningItem;
                return warning.FileName.Trim().Contains(txtSearchWarnings.Text);
            }
        }
        return false;
    }

这是我的 WarningItem 类代码:

public class WarningItem
{
    public string FullPath { get; set; }

    public string DirName { get; set; }

    public string FileName { get; set; }

    public string FileSize { get; set; }

    public string CreationDate { get; set; }

    public string Extension { get; set; }

    public Uri StatusImage { get; set; }
}

【问题讨论】:

  • 使用 CollectionViewSource,wpftutorial.net/dataviews.html
  • 感谢您的链接,但我仍然对如何进行过滤感到困惑,也许有人可以向我解释一下
  • 不需要每次View都调用CollectionViewSource.GetDefaultView来设置,因为它只检索一次对对象的引用,并在该对象的整个生命周期中保持它。在构造函数中执行一次,不要从 listBox 中获取,而是从 ObservableCollection 中获取。看看我的回答。
  • 感谢它现在像 Charm 一样工作!

标签: c# wpf listbox observablecollection


【解决方案1】:

我正在粘贴简单的示例,但类似的内容已被涵盖无数次,您需要深入研究 SO。以下示例检查集合 Names 是否包含元素,而该元素又包含搜索词。

private ObservableCollection<string> _names = new ObservableCollection<string>()
    {
        "Isabel", "Michal"
    };

    public ObservableCollection<string> Names
    {
        get { return _names; }
        set { _names = value; }
    }

    private ICollectionView View;

    public MainWindow()
    {
        InitializeComponent();
        ListBox.ItemsSource = Names;
        View = CollectionViewSource.GetDefaultView(Names);
    }

    private void TextBoxBase_OnTextChanged(object sender, TextChangedEventArgs e)
    {
        View.Filter = x => x.ToString().ToLower().Contains(((TextBox)sender).Text.ToLower());
    }

无需在 TextBoxChanged 事件中调用 CollectionViewSource.GetDefaultView(Names),因为 collectionView 被检索一次并保持引用。看看here

如果涉及到 MVVM 模式,你不应该使用代码隐藏,而不是

<TextBox TextChanged="TextBoxBase_OnTextChanged"/>

你应该有

  <TextBox Text="{Binding FilterText}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="TextChanged">
                <i:InvokeCommandAction Command="{Binding FilterListCommand}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </TextBox>

RelayCommand

【讨论】:

    猜你喜欢
    • 2020-12-01
    • 1970-01-01
    • 2013-01-27
    • 1970-01-01
    • 1970-01-01
    • 2019-02-03
    • 1970-01-01
    • 2014-05-21
    • 2017-04-02
    相关资源
    最近更新 更多