WPF DataGrid 表头筛选

我用DataGridExtensions 拓展包后,发现他筛选是进行内容变更后就直接筛选,这样会吃掉大量的内存,我想看看其他的方法或者它写有进行键盘回车再进行筛选,发现没找到(如果大佬了解的话,麻烦教教),在网络查找资料 也没有DataGridExtensions 相关的太多资料(国内).但是它是支持自定义控件的,我就自己参考它Demo,自己定义控件来实现

首先我们先安装一个NuGet包  在浏览里面输入 DataGridExtensions 找到并且安装。

这个是WPF DataGrid 控件的模块化扩展的开源网址 :https://gitee.com/mirrors_dotnet/DataGridExtensions?_from=gitee_searchicon-default.png?t=M4ADhttps://gitee.com/mirrors_dotnet/DataGridExtensions?_from=gitee_search

安装好之后 在你的页面上加上 

xmlns:dgx="urn:tom-englert.de/DataGridExtensions"

 然后再你的DataGrid 属性加上

dgx:DataGridFilter.IsAutoFilterEnabled="True"

你就发现 DataGridTextColumn 已经可以直接筛选查找了。

如果是 DataGridTemplateColumn的话 要加上SortMemberPath属性 列如:

<DataGridTemplateColumn
                    Header="名称"
                    SortMemberPath="Name">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

但是 这样是内容变更筛选 ,所以要根据它的拓展特性来自定义控件。 首先先来创建一个用户控件,在页面加上

xmlns:dgx="clr-namespace:DataGridExtensions;assembly=DataGridExtensions"

然后开始调整你样式,我直接把我的AXML代码贴出来了

<Control
    x:Class="ViewModelLocator.Controls.SeekTextBoxControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:dgx="clr-namespace:DataGridExtensions;assembly=DataGridExtensions"
    xmlns:local="clr-namespace:ViewModelLocator.Controls"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    d:DesignHeight="450"
    d:DesignWidth="800"
    mc:Ignorable="d">
    <Control.Template>
        <ControlTemplate>
            <Grid>
                <Control Style="{DynamicResource {x:Static dgx:DataGridFilter.IconStyleKey}}" />
                <StackPanel
                    x:Name="inputPanel"
                    Margin="4,0,2,0"
                    Background="White"
                    Orientation="Horizontal">
                    <TextBox
                        x:Name="textBox"
                        MinWidth="20"
                        KeyDown="textBox_KeyDown"
                        TextChanged="textBox_TextChanged" />
                </StackPanel>
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger SourceName="textBox" Property="Text" Value="">
                    <Setter TargetName="inputPanel" Property="Opacity" Value="0" />
                </Trigger>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter TargetName="inputPanel" Property="Opacity" Value="1" />
                </Trigger>
                <Trigger SourceName="textBox" Property="IsFocused" Value="True">
                    <Setter TargetName="inputPanel" Property="Opacity" Value="1" />
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Control.Template>
</Control>

然后到后台数据处理

using DataGridExtensions;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace ViewModelLocator.Controls
{
    /// <summary>
    /// SeekTextBoxControl.xaml 的交互逻辑
    /// </summary>
    public partial class SeekTextBoxControl 
    {
        private TextBox? _textBox;
        public SeekTextBoxControl()
        {
            InitializeComponent();
        }
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            _textBox = Template.FindName("textBox", this) as TextBox;
        }
        /// <summary>
        /// 变更事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            var text = ((TextBox)sender).Text;
            if (string.IsNullOrWhiteSpace(text))
            {
                Filter = new ContentFilter(text);
                //Filter = !double.TryParse(text, NumberStyles.Any, CultureInfo.CurrentCulture, out var threshold) ? null : new ContentFilter(threshold);
            }
        }
        /// <summary>
        /// 键盘变动事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textBox_KeyDown(object sender, KeyEventArgs e)
        {
            var text = ((TextBox)sender).Text;
            if (e.Key == Key.Enter)
            {
                Filter =  new ContentFilter(text);
            }
        }

        public IContentFilter? Filter
        {
            get => (IContentFilter?)GetValue(FilterProperty);
            set => SetValue(FilterProperty, value);
        }
        /// <summary>
        /// 标识Filter依赖项属性
        /// </summary>
        public static readonly DependencyProperty FilterProperty =
            DependencyProperty.Register("Filter", typeof(IContentFilter), typeof(SeekTextBoxControl), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (o, args) => ((SeekTextBoxControl)o).Filter_Changed(args.NewValue)));

        private void Filter_Changed(object newValue)
        {
            var textBox = _textBox;
            if (textBox == null)
                return;

            textBox.Text = (newValue as ContentFilter)?.Value ?? string.Empty;
        }


        private class ContentFilter : IContentFilter
        {
            private readonly string _threshold;

            public ContentFilter(string threshold)
            {
                _threshold = threshold;
            }

            public bool IsMatch(object? value)
            {
                if (value == null)
                    return false;
                //var ds = double.TryParse(value.ToString(), out var j) && (j > _threshold);
                return value.ToString().Contains(_threshold.ToLower());
            }

            public string Value =>  _threshold.ToString(CultureInfo.CurrentCulture);
        }
    }
}

然后再回到你的主页面,添加控件所以在位置空间  (Controls是我的文件夹 用户控件放再里面)

xmlns:controls="clr-namespace:ViewModelLocator.Controls"

添加Resources 列如:

<Window.Resources>
        <ResourceDictionary>
            <ControlTemplate x:Key="textBoxFilter">
                <controls:SeekTextBoxControl Filter="{Binding Path=Filter, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dgx:DataGridFilterColumnControl}}" />
            </ControlTemplate>
        </ResourceDictionary>
    </Window.Resources>

开始调用到Column中

dgx:DataGridFilterColumn.Template="{StaticResource textBoxFilter}"

就这样 完成了 内容回车才会执行,清空textbox也会执行一次,如果有什么问题或者更好的方案 ,欢迎留言。

欢迎转载、使用、重新发布,但务必保留文章署名FalyEnd(包含链接: https://www.cnblogs.com/falychen/

### 回答1: WPF DataGrid复合表头用于在表格中显示多级标题。在DataGrid中,复合表头可以以层次结构的方式组织和显示列标题,使用户更好地理解和管理表格数据。 要创建复合表头,我们可以使用DataGridTemplateColumn和HeaderTemplate属性。首先,我们需要定义一个复合表头模板,其中包含多个层次结构的标题。可以使用StackPanel或Grid等容器控件来组织这些层次结构。 下面是一个示例,展示了如何创建一个具有两个层次结构的复合表头: ```xaml <DataGrid> <DataGrid.Columns> <DataGridTemplateColumn> <DataGridTemplateColumn.HeaderTemplate> <DataTemplate> <Grid> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Text="第一级标题" /> <TextBlock Grid.Row="1" Text="第二级标题" /> </Grid> </DataTemplate> </DataGridTemplateColumn.HeaderTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> ``` 上述示例中,我们创建了一个DataGridTemplateColumn,并将其HeaderTemplate属性设置为一个包含两个TextBlock的Grid。这样,第一级标题和第二级标题就以层次结构的方式显示在表头中。 通过使用嵌套的容器控件和定义适当的布局,我们可以创建更复杂的多级标题结构。在实际使用中,我们可以根据需求进行自定义和扩展,以满足复杂表格的显示需求。 总的来说,WPF DataGrid复合表头提供了一种更灵活和直观的方式来管理和展示表格数据,使用户能够更好地理解和操作数据。 ### 回答2: WPF DataGrid是一个强大的控件,允许我们通过使用复合表头来组织和显示数据。复合表头是指一个表头下面有多个子表头的情况。 要在WPF DataGrid中使用复合表头,我们需要使用DataGrid的ColumnHeaderStyle属性来自定义表头的样式。我们可以使用StackPanel控件来嵌套多个表头,并设置每个表头的样式和内容。 首先,我们需要创建一个StackPanel来作为根表头。然后,我们可以使用TextBlock或其他控件来添加子表头,并设置它们的样式和内容。我们可以使用Margin属性来设置每个子表头之间的间距。 接下来,我们需要将StackPanel添加到DataGrid的ColumnHeaderStyle属性中。这样,每个列的表头都会根据这个样式进行显示。 如果我们想要在复合表头中显示具有层次结构的数据,可以使用HierarchicalDataTemplate来定义每个子表头的内容。HierarchicalDataTemplate允许我们绑定嵌套的数据,并在子表头中显示它们。 最后,我们可以根据需要自定义表头的外观,比如设置颜色、字体等属性。我们可以使用Setter和Trigger来实现这些自定义样式。 总之,WPF DataGrid允许我们通过使用复合表头来组织和显示数据。我们可以使用StackPanel来创建复合表头,并使用ColumnHeaderStyle属性和HierarchicalDataTemplate来自定义表头的样式和内容。通过这种方式,我们可以创建出功能强大且易于使用的数据表格。 ### 回答3: WPF DataGrid是一种用于呈现和编辑数据的控件,它支持复合表头。复合表头是指表格中的表头可以跨越多列或多行,提供更灵活和复杂的布局。 要实现复合表头,我们可以使用DataGrid的列合并功能。首先,在DataGrid的XAML代码中,我们可以定义多个DataGridTextColumn或其他类型的列,并为每个列设置相应的属性和样式。然后,我们可以在需要合并的列中使用DataGrid.ColumnHeaderStyle属性来设置合并样式。 可以通过设置DataGrid.ColumnHeaderStyle中的ContentTemplate属性来定义自定义表头。在ContentTemplate中,我们可以使用Grid来创建一个包含多个单元格的布局。通过设置Grid的列或行的宽度和高度,我们可以控制表头中每个单元格的大小和位置。还可以在每个单元格中添加文本或其他控件来自定义表头的内容。 除了定义自定义表头的布局,我们还可以使用DataGrid.ColumnHeaderStyle中的其他属性来设置表头的外观,如前景色、背景色、字体样式等。这样,我们就能够创建出符合我们需求的复合表头了。 在绑定数据时,我们只需要将数据源的属性与对应的表格列进行绑定,DataGrid会自动将数据显示在表格中。由于复合表头的实现是基于DataGrid的列合并功能,因此绑定数据时并不需要额外的操作。 通过实现复合表头,我们可以打造出专业而美观的数据展示界面,提高用户的数据浏览和编辑体验。同时,WPF DataGrid的强大功能和灵活性也使得复合表头的实现变得简单而有效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Faly晨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值