C# 按多个标准筛选WPF数据网格
我想通过三列实现类似Excel的datagrid过滤器 这是我的密码:C# 按多个标准筛选WPF数据网格,c#,wpf,datatable,datagrid,C#,Wpf,Datatable,Datagrid,我想通过三列实现类似Excel的datagrid过滤器 这是我的密码: using System.Data.Odbc; using System.Windows; using System.Data; namespace DB_inspector { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary&
using System.Data.Odbc;
using System.Windows;
using System.Data;
namespace DB_inspector
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
OdbcConnection dbConnection = new OdbcConnection("Driver={Pervasive ODBC Client Interface};ServerName=875;dbq=@DBFS;Uid=Username;Pwd=Password;");
string strSql = "select NRO,NAME,NAMEA,NAMEB,ADDRESS,POSTA,POSTN,POSTADR,COMPANYN,COUNTRY,ID,ACTIVE from COMPANY";
dbConnection.Open();
OdbcDataAdapter dadapter = new OdbcDataAdapter();
dadapter.SelectCommand = new OdbcCommand(strSql, dbConnection);
DataTable table = new DataTable("COMPANY");
dadapter.Fill(table);
DataGrid1.DataContext = table;
DataGrid1.ItemsSource = table.DefaultView;
dadapter.Update(table);
dbConnection.Close();
}
private void TextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
DataView dv = DataGrid1.ItemsSource as DataView;
string filter = NameSearch.Text;
if (string.IsNullOrEmpty(filter))
dv.RowFilter = null;
else
dv.RowFilter = string.Format("NAME Like '%{0}%'", filter);
}
private void TextBox_TextChanged_1(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
DataView dv = DataGrid1.ItemsSource as DataView;
string filter = ActiveSearch.Text;
if (string.IsNullOrEmpty(filter))
dv.RowFilter = null;
else
dv.RowFilter = string.Format("ACTIVE Like '%{0}%'", filter);
}
private void CustomerNumberSearch_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
DataView dv = DataGrid1.ItemsSource as DataView;
string filter = CustomerNumberSearch.Text;
if (string.IsNullOrEmpty(filter))
dv.RowFilter = null;
else
dv.RowFilter = string.Format("NRO Like '%{0}%'", filter); //this should be "Begins with" not "Like"
}
}
}
使用System.Data.Odbc;
使用System.Windows;
使用系统数据;
名称空间数据库检查器
{
///
///MainWindow.xaml的交互逻辑
///
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
}
私有无效按钮\u单击(对象发送者,路由目标e)
{
OdbcConnection dbConnection=newodbcconnection(“驱动程序={普及ODBC客户端接口};服务器名=875;dbq=@DBFS;Uid=用户名;Pwd=密码;”;
string strSql=“选择NRO、名称、名称A、名称B、地址、邮资、邮资N、邮资DR、公司YN、国家/地区、ID、公司活动”;
dbConnection.Open();
OdbcDataAdapter dadapter=新的OdbcDataAdapter();
dadapter.SelectCommand=newodbccommand(strSql,dbConnection);
数据表=新数据表(“公司”);
数据填充(表格);
DataGrid1.DataContext=表;
DataGrid1.ItemsSource=table.DefaultView;
数据更新(表);
dbConnection.Close();
}
私有无效文本框\u TextChanged(对象发送方,System.Windows.Controls.textchangedventargs e)
{
DataView dv=DataGrid1.ItemsSource作为DataView;
字符串过滤器=NameSearch.Text;
if(string.IsNullOrEmpty(筛选器))
dv.RowFilter=null;
其他的
dv.RowFilter=string.Format(“名称类似“{0}%”,filter);
}
私有无效文本框\u TextChanged\u 1(对象发送者,System.Windows.Controls.textchangedventargs e)
{
DataView dv=DataGrid1.ItemsSource作为DataView;
字符串过滤器=ActiveSearch.Text;
if(string.IsNullOrEmpty(筛选器))
dv.RowFilter=null;
其他的
dv.RowFilter=string.Format(“像“{0}%”一样处于活动状态,筛选器);
}
private void CustomerNumber搜索\ U文本已更改(对象发件人,System.Windows.Controls.TextChangedEventArgs e)
{
DataView dv=DataGrid1.ItemsSource作为DataView;
字符串过滤器=CustomerNumber搜索.Text;
if(string.IsNullOrEmpty(筛选器))
dv.RowFilter=null;
其他的
dv.RowFilter=string.Format(“类似NRO的“{0}%”,filter);//这应该是“以”开头,而不是“类似”
}
}
}
XAML
我想为列NRO
和ACTIVE
实施过滤器,以便在加载列NRO
中的数据时,数字仅以3开头,列中的ACTIVE
值仅以1开头。在ACTIVE
中,有值1和0(1为ACTIVE,0为notactive)
我当前的设置仅按一个条件进行筛选。如何使这三个标准都正确运行 您可以修改数据库查询,让数据库更高效地完成工作。
但是如果您仍然喜欢使用C#,那么可以使用LINQ来过滤
数据表
:
main window.xaml
<Window>
<Window.DataContext>
<ViewModel />
</Window.DataContext>
<DataGrid ItemsSource={Binding Data} />
</Window>
<Window x:Class="DB_inspector.MainWindow"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Liinos_inspector"
mc:Ignorable="d"
Title="DB database inspector" Height="595.404" Width="1005.571">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="11*"/>
<RowDefinition Height="553*"/>
</Grid.RowDefinitions>
<DataGrid x:Name="DataGrid1" Margin="0,51,0,0" Grid.Row="1"
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type MainWindow}}, Path=FilteredData}" />
<Image Height="41" Margin="847,10,10,502" Width="141" Source="Logo_small.jpg" Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Top"/>
<TextBox x:Name="NameSearch" HorizontalAlignment="Left" Height="23" Margin="77,14,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="409" Grid.Row="1"
TextChanged="OnNameSearchTextBox_TextChanged"/>
<Button Content="Refrsh" HorizontalAlignment="Left" Height="23" Margin="736,14,0,0" VerticalAlignment="Top" Width="72" Click="Button_Click" Grid.Row="1" Background="#FF51C951" BorderBrush="{x:Null}" Foreground="White"/>
<CheckBox x:Name="ActiveSearch" HorizontalAlignment="Left" Height="23" Margin="502,14,0,0" Grid.Row="1" VerticalAlignment="Top" Width="66"
IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type MainWindow}}, Path=IsActiveFilterValue}" />
<TextBox x:Name="CustomerNumberSearch" HorizontalAlignment="Left" Height="23" Margin="580,14,0,0" Grid.Row="1" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="82"
TextChanged="OnCustomerNumberSearch_TextChanged"/>
<ProgressBar x:Name="ProgressBar" HorizontalAlignment="Left" Height="10" Margin="0,1,0,0" VerticalAlignment="Top" Width="998" BorderBrush="{x:Null}" Background="{x:Null}"/>
<Button Content="Button" HorizontalAlignment="Left" Height="23" Margin="680,14,0,0" Grid.Row="1" VerticalAlignment="Top" Width="51" Click="Button_Click_1"/>
</Grid>
</Window>
更新 这是基于您发布的代码的解决方案。我将
文本框
替换为使用复选框
过滤活动
列,以添加一些类型安全性(防止无效输入,例如,按字母顺序)。我还使用数据绑定将DataGrid
连接到DataTable
。您应该更喜欢在代码隐藏上使用数据绑定,并尽可能多地在XAML中实现:
main window.xaml
<Window>
<Window.DataContext>
<ViewModel />
</Window.DataContext>
<DataGrid ItemsSource={Binding Data} />
</Window>
<Window x:Class="DB_inspector.MainWindow"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Liinos_inspector"
mc:Ignorable="d"
Title="DB database inspector" Height="595.404" Width="1005.571">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="11*"/>
<RowDefinition Height="553*"/>
</Grid.RowDefinitions>
<DataGrid x:Name="DataGrid1" Margin="0,51,0,0" Grid.Row="1"
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type MainWindow}}, Path=FilteredData}" />
<Image Height="41" Margin="847,10,10,502" Width="141" Source="Logo_small.jpg" Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Top"/>
<TextBox x:Name="NameSearch" HorizontalAlignment="Left" Height="23" Margin="77,14,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="409" Grid.Row="1"
TextChanged="OnNameSearchTextBox_TextChanged"/>
<Button Content="Refrsh" HorizontalAlignment="Left" Height="23" Margin="736,14,0,0" VerticalAlignment="Top" Width="72" Click="Button_Click" Grid.Row="1" Background="#FF51C951" BorderBrush="{x:Null}" Foreground="White"/>
<CheckBox x:Name="ActiveSearch" HorizontalAlignment="Left" Height="23" Margin="502,14,0,0" Grid.Row="1" VerticalAlignment="Top" Width="66"
IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type MainWindow}}, Path=IsActiveFilterValue}" />
<TextBox x:Name="CustomerNumberSearch" HorizontalAlignment="Left" Height="23" Margin="580,14,0,0" Grid.Row="1" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="82"
TextChanged="OnCustomerNumberSearch_TextChanged"/>
<ProgressBar x:Name="ProgressBar" HorizontalAlignment="Left" Height="10" Margin="0,1,0,0" VerticalAlignment="Top" Width="998" BorderBrush="{x:Null}" Background="{x:Null}"/>
<Button Content="Button" HorizontalAlignment="Left" Height="23" Margin="680,14,0,0" Grid.Row="1" VerticalAlignment="Top" Width="51" Click="Button_Click_1"/>
</Grid>
</Window>
MainWindow.xaml.cs
public class ViewModel
{
public DataTable Data { get; set; }
public ViewModel()
{
this.Data = new DataTable();
}
// Button ICommand handler
private void ExecuteGetDataCommand(object param)
{
DataTable dataTable = QueryDatabase();
// Filter DataTable using LINQ
this.Data = dataTable
.AsEnumerable()
.Where(row => row["NRO"].ToString().StartsWith("3")
&& row["ACTIVE"].ToString().StartsWith("1"))
.CopyToDataTable();
}
private DataTable QueryDatabase()
{
OdbcConnection dbConnection = new OdbcConnection("Driver={Pervasive ODBC Client Interface};ServerName=875;dbq=@DBFS;Uid=Username;Pwd=Password;");
string strSql = "select NRO,NAME,NAMEA,NAMEB,ADDRESS,POSTA,POSTN,POSTADR,COMPANYN,COUNTRY,ID,ACTIVE from COMPANY";
dbConnection.Open();
OdbcDataAdapter dadapter = new OdbcDataAdapter();
dadapter.SelectCommand = new OdbcCommand(strSql, dbConnection);
DataTable table = new DataTable("COMPANY");
dadapter.Fill(table);
return table;
}
}
public partial class MainWindow : Window
{
public static readonly DependencyProperty FilteredDataProperty = DependencyProperty.Register(
"FilteredData",
typeof(DataTable),
typeof(MainWindow));
public DataTable FilteredData
{
get { return (DataTable)GetValue(FilteredDataProperty); }
set { SetValue(FilteredDataProperty, value); }
}
public static readonly DependencyProperty IsActiveFilterValueProperty = DependencyProperty.Register(
"IsActiveFilterValue",
typeof(bool),
typeof(MainWindow),
new PropertyMetadata(false, OnIsActiveFilterValueChanged));
public bool IsActiveFilterValue
{
get { return (bool)GetValue(IsActiveFilterValueProperty); }
set { SetValue(IsActiveFilterValueProperty, value); }
}
private DataTable UnfilteredData { get; set; }
private String NameFilterValue { get; set; }
private int CustomerNumberFilterValue { get; set; }
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
string connectionString = "Driver={Pervasive ODBC Client Interface};ServerName=875;dbq=@DBFS;Uid=Username;Pwd=Password;";
string queryString = "select NRO,NAME,NAMEA,NAMEB,ADDRESS,POSTA,POSTN,POSTADR,COMPANYN,COUNTRY,ID,ACTIVE from COMPANY";
// using-statement will cleanly close and dispose unmanaged resources i.e. IDisposable instances
using (OdbcConnection dbConnection = new OdbcConnection(connectionString))
{
dbConnection.Open();
OdbcDataAdapter dadapter = new OdbcDataAdapter();
dadapter.SelectCommand = new OdbcCommand(queryString, dbConnection);
this.UnfilteredData = new DataTable("COMPANY");
dadapter.Fill(this.UnfilteredData);
this.FilteredData = this.UnfilteredData;
}
}
private void ApplyFilterOnDataTable()
{
// Filter DataTable using LINQ
this.FilteredData = this.UnfilteredData
.AsEnumerable()
.Where(row =>
string.IsNullOrWhiteSpace(this.NameFilterValue)
? true // Filter criteria is ignored, when input is empty or null
: row["NAME"].StartsWith(this.NameFilterValue)
&& this.CustomerNumberFilterValue < 0
? true // Filter criteria is ignored, when value is < 0
: row["NRO"].ToString().StartsWith(this.CustomerNumberFilterValue.ToString())
&& this.IsActiveFilterValue
? row["ACTIVE"].ToString().Equals("1")
: true) // Filter criteris is ignored, when CheckBox is unchecked
.CopyToDataTable();
}
private void OnNameSearchTextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
this.NameFilterValue = NameSearch.Text;
ApplyFilterOnDataTable();
}
private static void OnIsActiveFilterValueChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var _this = d as MainWindow;
_this.ApplyFilterOnDataTable();
}
private void OnCustomerNumberSearch_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
// Check if input is numeric
this.CustomerNumberFilterValue = Int32.TryParse(CustomerNumberSearch.Text, out int number)
? number
: -1; // Parsing failed -> not a numeric value. -1 will disable this filter criteria
ApplyFilterOnDataTable();
}
}
公共部分类主窗口:窗口
{
public static readonly dependencProperty filteredataProperty=dependencProperty.Register(
“过滤数据”,
类型(数据表),
类型(主窗口);
公共数据表筛选器数据
{
get{return(DataTable)GetValue(FilteredDataProperty);}
集合{SetValue(FilteredDataProperty,value);}
}
公共静态只读DependencyProperty IsActivieFilterValueProperty=DependencyProperty.Register(
“IsActivifilterValue”,
类型(bool),
类型(主窗口),
新的PropertyMetadata(false,OnIsActiveFilterValueChanged));
公共布尔IsActiveFilterValue
{
获取{return(bool)GetValue(IsActiveFilterValueProperty);}
set{SetValue(isActivifilterValueProperty,value);}
}
私有数据表未筛选数据{get;set;}
私有字符串NameFilterValue{get;set;}
private int CustomerNumberFilterValue{get;set;}
公共主窗口()
{
初始化组件();
}
私有无效按钮\u单击(对象发送者,路由目标e)
{
string connectionString=“Driver={普及ODBC客户端接口};ServerName=875;dbq=@DBFS;Uid=Username;Pwd=Password;”;
string queryString=“选择NRO、名称、名称A、名称B、地址、邮资、邮资N、邮资DR、公司YN、国家/地区、ID、公司活动”;
//语句将干净地关闭和处置非托管资源,即IDisposable实例
正在使用(OdbcConnection dbConnection=新OdbcConnection(connectionString))
{
dbConnection.Open();
OdbcDataAdapter dadapter=新的OdbcDataAdapter();
dadapter.SelectCommand=新的OdbcCommand(queryString、dbConnection);
this.UnfilteredData=新数据表(“公司”);
dadapter.Fill(此为未过滤数据);
this.FilteredData=this.UnfilteredData;
}
}
私有void ApplyFilterOnDataTable()
{
//筛选数据选项卡