我用DataGridExtensions 拓展包后,发现他筛选是进行内容变更后就直接筛选,这样会吃掉大量的内存,我想看看其他的方法或者它写有进行键盘回车再进行筛选,发现没找到(如果大佬了解的话,麻烦教教),在网络查找资料 也没有DataGridExtensions 相关的太多资料(国内).但是它是支持自定义控件的,我就自己参考它Demo,自己定义控件来实现
首先我们先安装一个NuGet包 在浏览里面输入 DataGridExtensions 找到并且安装。
这个是WPF DataGrid 控件的模块化扩展的开源网址 :https://gitee.com/mirrors_dotnet/DataGridExtensions?_from=gitee_searchhttps://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/ )