【问题标题】:Need to implement a filter to my WPF Datagrid using Textbox in C#需要使用 C# 中的文本框对我的 WPF Datagrid 实现过滤器
【发布时间】:2021-08-13 23:49:10
【问题描述】:

我有一个 WPF 数据网格,我在其中使用 itemsource 填充数据表中的数据。现在我想为我的 Datagrid 应用文本框过滤器或(如果可能,将过滤器应用到列标题)。我对 WPF 很陌生,所以任何人都可以帮我解决这个问题。

注意:我没有使用 MVVM,我只是使用简单的 WPF 数据网格

Currently my code is like below:
XAML Code:
-------------------

 <Page.Resources>
        <LinearGradientBrush x:Key="HeaderBrush" StartPoint="0.5,0" EndPoint="0.5,1">
            <GradientStop Color="#FF6B6EB9" Offset="0"/>
            <GradientStop Color="#FF6B6EB9" Offset="1"/>
            <GradientStop Color="#FF6B6EB9" Offset="0.509"/>
            <GradientStop Color="#FF6B6EB9" Offset="0.542"/>
            <GradientStop Color="#FF6B6EB9" Offset="0.542"/>
            <GradientStop Color="#FF9699DC" Offset="0.904"/>
        </LinearGradientBrush>

        <LinearGradientBrush x:Key="HeaderBorderBrush" StartPoint="0.5,0" EndPoint="0.5,1">
            <GradientStop Color="#FF1060D1" Offset="0.614"/>
            <GradientStop Color="#FF316BD5" Offset="0.853"/>
            <GradientStop Color="#FFBBD3ED" Offset="1"/>
        </LinearGradientBrush>

        <Style x:Key="HeaderStyle" TargetType="DataGridColumnHeader">
            <Setter Property="Background" Value="{StaticResource HeaderBrush}" />
            <Setter Property="Foreground" Value="White" />
            <Setter Property="BorderBrush" Value="{StaticResource HeaderBorderBrush}" />
            <Setter Property="BorderThickness" Value="0" />
            <Setter Property="SnapsToDevicePixels" Value="True" />
            <Setter Property="HorizontalContentAlignment" Value="Left" />
            <Setter Property="MinWidth" Value="0" />
            <Setter Property="MinHeight" Value="30" />
            <Setter Property="Cursor" Value="Hand" />
        </Style>
    </Page.Resources>

    <Grid>
        <DataGrid Name="dgExcel"  LoadingRow="dgExcel_LoadingRow" RowEditEnding="dgExcel_RowEditEnding" ColumnHeaderStyle="{StaticResource HeaderStyle}" CanUserDeleteRows="True" AutoGenerateColumns="True" AutoGeneratingColumn="dgExcel_AutoGeneratingColumn" ItemsSource = "{Binding}" ColumnWidth="Auto"  SelectionChanged="dgExcel_SelectionChanged" CanUserAddRows="True"  Loaded="dgExcel_Loaded" CellEditEnding="dgExcel_CellEditEnding" ScrollViewer.CanContentScroll="True" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" GridLinesVisibility="Horizontal" AlternatingRowBackground="#FFF3F3F3">
        </DataGrid>
    </Grid>
 

加载wpf数据网格的代码文件:

 private void dgExcel_Loaded(object sender, RoutedEventArgs e)
 {
    string ConeectionString = String.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source='C:\\Test.xlsx';" + "Extended Properties=\"Excel 12.0 Xml;HDR=YES\"");
            OleDbConnection oconn = new OleDbConnection(ConeectionString);
            System.Data.DataSet DtSet;
            System.Data.OleDb.OleDbDataAdapter MyCommand;
            MyCommand = new System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", oconn);
            MyCommand.TableMappings.Add("Table", "TestTable");
            DtSet = new System.Data.DataSet();
            MyCommand.Fill(DtSet);
            dgExcel.DataContext = DtSet.Tables[0];
            System.Data.DataTable dt = new System.Data.DataTable();
            //actionsGrid.ItemsSource = DtSet.DefaultViewManager;
            dt = DtSet.Tables[0];
            dgExcel.ItemsSource = dt.DefaultView;  
            oconn.Close();
        }

【问题讨论】:

    标签: c# filter datagrid


    【解决方案1】:

    首先,添加一个文本框。您可以找到带有按钮的更高级的文本框来清除文本,或者主动点击按钮进行搜索,但现在只是一个简单的文本框。确保已命名,并添加 TextChanged 事件处理程序。

    <TextBox x:Name="searchBox" TextChanged="SearchTextBox_TextChanged"/>
    

    然后您想连接到您的CollectionView。您可以直接分配它,或者在 XAML 代码中使用 CollectionViewSource 元素。这是一个基本版本:

    <Window.Resources>
        <CollectionViewSource x:Key="collectionView" Source="{Binding OrderCollection}"
                              Filter="CollectionViewSource_Filter"/>
    </Window.Resources>
    

    这假定已在后台代码或视图模型中设置了ObservableCollection

    public ObservableCollection<Orders> OrderCollection { get; } = //collection of orders
    

    DataGridItemSource 将指向CollectionViewSource 作为静态资源绑定。还有其他方法可以构建它(例如,直接连接到dt.DefaultView),但我会留给您配置。

    TextBox 的 text changed 事件处理程序中,您想刷新视图,因此每次用户输入新字符时,它都会重新评估过滤器:

    private void SearchTextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        RefreshView();
    }
    
    void RefreshView()
    {
        var viewSource = (CollectionViewSource)Resources["collectionView"];
        viewSource?.View?.Refresh();
    }
    

    警告:这不会处理粘贴的文本。为此有一组单独的事件。

    当视图刷新时,它将通过集合视图的Filter 运行ItemsSource 的各个项目。然后设置是否接受每个项目。

    private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
    {
        if (e.Item is DataRow row)
        {
            if (searchBox.HasText)
            {
                e.Accepted = Filter(row, searchBox.Text);
            }
            else
            {
                e.Accepted = true;
            }
        }
        else
        {
            e.Accepted = false;
        }
    }
    
    private bool Filter(DataRow row, string filterText)
    {
        // check if row matches the filterText
        // check whichever columns of the row are appropriate
        return true;
    }
    

    这些东西可以通过不同的方式连接在一起,但这应该涵盖基本必需品。我没有检查我期望为您的数据使用的数据类型是否是通过事件处理程序传递的实际数据类型,因此请务必仔细检查。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-05
      • 2011-08-30
      • 2019-07-16
      • 2017-04-26
      • 2017-09-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多