过滤/搜索绑定列表框

Filter / Search binded Listbox

嘿,

我得到了一个绑定到 ObservableCollection 的 ListBox,现在我正在尝试实现一个 Search / Filter 函数。但它不起作用......尝试了一切:(

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

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

这是我到目前为止尝试过的 .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 Class 代码:

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

我正在粘贴简单的示例,但类似的内容已涵盖无数次,您需要深入研究 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