如何过滤DataGrid中的记录?

时间:2017-08-03 16:05:18

标签: c# wpf search visual-studio-2017 wpfdatagrid

我正在尝试根据搜索框过滤所选列的数据。到目前为止,基于这篇文章,我有这个:filter wpf datagrid values from a textbox

DataGridCollection:

public ICollectionView DataGridCollection
{
   get { return _dataGridCollection; }
   set { _dataGridCollection = value; NotifyPropertyChanged("DataGridCollection"); }
}

过滤器集合:

private void FilterCollection()
{
    if (_dataGridCollection != null)
    {
        _dataGridCollection.Refresh();
    }
}

数据来源:

DataTable pixsellOrders = SqlConnect(query);    
Grid.Dispatcher.Invoke(DispatcherPriority.Normal, (ThreadStart)delegate { DataGridCollection = CollectionViewSource.GetDefaultView(pixsellOrders); });
DataGridCollection.Filter = new Predicate<object>(filter);

过滤按钮(右键单击):

private void MenuItem_Click(object sender, RoutedEventArgs e)
    {
        string filter = "";
        FilterBox.Dispatcher.Invoke(DispatcherPriority.Normal, (ThreadStart)delegate { filter = FilterBox.Text; });

        if (filter == "")
        {
            Console.WriteLine("no filter");
            return;
        }
        else
        {
            Console.WriteLine(filter);
            FilterCollection();
        }
    }

基于例子:

private bool filter(object item)
    {
        if (item.Subject.Contains(_searchstr) || item.Reference.Contains(searchstr))
        {
            return true;
        }
        return false;
    }

XAML:

<Grid DataContext="{Binding ElementName=ResultsWindow}">
    <DataGrid x:Name="Grid" HorizontalAlignment="Stretch" Height="Auto" Margin="20,45,20,60" VerticalAlignment="Stretch" Width="Auto" ItemsSource="{Binding DataGridCollection}"  >
        <DataGrid.Resources>
            <ContextMenu x:Key="DataGridColumnHeaderContextMenu">
                <MenuItem Header="Filter" Click="MenuItem_Click"/>
            </ContextMenu>
            <Style TargetType="{x:Type DataGridColumnHeader}">
                <Setter Property="ContextMenu"
                Value="{StaticResource DataGridColumnHeaderContextMenu}"/>
            </Style>
        </DataGrid.Resources>
    </DataGrid>
    <Button x:Name="BtnBack" Content="Back" HorizontalAlignment="Right" Margin="0,0,20,20" VerticalAlignment="Bottom" Width="76" Click="BtnBack_Click"/>
    <TextBox Height="27" Margin="65,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" HorizontalAlignment="Left" Width="524" Name="FilterBox"/>
    <Label Content="Filter" HorizontalAlignment="Left" Margin="20,10,0,0" VerticalAlignment="Top"/>
</Grid>

在示例中,列在过滤器中显式声明(private bool过滤器)。我想只过滤选中的列(右键单击列标题并从上下文菜单中选择过滤器)。我如何调整我必须做的事情?不幸的是,我对XAML没有多少经验。

2 个答案:

答案 0 :(得分:1)

过滤DataTable的方法是设置RowFilterhttps://msdn.microsoft.com/en-us/library/system.data.dataview.rowfilter(v=vs.110).aspxDataView属性。这里有一些例子:http://www.csharp-examples.net/dataview-rowfilter/

您无法使用DataView的{​​{1}}属性过滤DataTable的{​​{1}}。这不受支持:

Why errors when filters DataTable with CollectionView?

答案 1 :(得分:0)

通常,您会在搜索框中使用一些特殊语法实现逐列搜索功能,即column:value

private static bool TryGetValue(string search, out string column, out string value)
{
    // just an example, should be made more robust

    column = null;

    value = null;

    var match = Regex.Match(search, @"^(\w+):(.*)$");

    if (!match.Success)
        return false;

    column = match.Groups[1].Value.Trim();
    value = match.Groups[2].Value.Trim();

    return true;
}

示例:

var strings = new[]
{
    "column1:abcd",
    "qwerty:asdfg",
    "1234:5678"
};

foreach (var search in strings)
{
    string column;
    string value;

    if (TryGetValue(search, out column, out value))
    {
        Console.WriteLine($"Column: '{column}'\tValue: '{value}'");
    }
    else
    {
        Console.WriteLine("Invalid syntax");
    }
}

结果:

Column: 'column1'       Value: 'abcd'
Column: 'qwerty'        Value: 'asdfg'
Column: '1234'  Value: '5678'

通过这样做,用户负责填充列,您的代码将不会被硬编码。

如果搜索查询中没有前缀列,则可以通过进行增强,这意味着搜索所有列

此外,您可以在该搜索框中实施自动建议。

等...