![](/img/trans.png)
[英]Filter WPF DataGrid based on TextBoxes and CheckBoxes MVVM
[英]Filter WPF DataGrid (DataTable) based on values from several TextBoxes MVVM
我一直在尝试设置基于 4 个文本框的过滤器。 如果第一个文本框不为空 -> 然后基于此进行过滤,如果第一个和第二个文本框不为空,则从这两个文本框中组合过滤器等。我希望我的过滤器像这样工作http://www.tablefilter.com/auto-过滤器.html
如您所见,我尝试了多种变体,但我不断收到下面提供的错误。 任何建议如何让它工作?
这是我的代码:
public void EnableRowFiltering()
{
StringBuilder sb = new StringBuilder();
if (this.YRNROSearchKey != string.Empty)
{
sb.Append($"YRNRO LIKE '%{this.YRNROSearchKey}%' AND ");
}
if (this.HAKUNIMISearchKey != string.Empty)
{
sb.Append($"HAKUNIMI LIKE '%{this.HAKUNIMISearchKey}%' AND ");
}
if (this.GROUPSearchKey != string.Empty)
{
sb.Append($"KONSERNI LIKE '%{this.GROUPSearchKey}%' AND ");
}
if (this.BUSINESSIDSearchKey != string.Empty)
{
sb.Append($"LY LIKE '%{this.BUSINESSIDSearchKey}%' AND ");
}
// I have tried also this way without success
// this.MainDataTable.DefaultView.RowFilter = YRNRO + HAKUNIMI + GROUP + BUSINESSID;
string YRNRO = string.IsNullOrEmpty(this.YRNROSearchKey) ? "" : $"YRNRO LIKE '{this.YRNROSearchKey}*'";
string HAKUNIMI = string.IsNullOrEmpty(this.HAKUNIMISearchKey) ? "" : $" AND HAKUNIMI LIKE '{this.HAKUNIMISearchKey}*'";
string GROUP = string.IsNullOrEmpty(this.GROUPSearchKey) ? "" : $" AND KONSERNI LIKE '{this.GROUPSearchKey}*'";
string BUSINESSID = string.IsNullOrEmpty(this.BUSINESSIDSearchKey) ? "" : $" AND LY LIKE '{this.BUSINESSIDSearchKey}*'";
this.MainDataTable.DefaultView.RowFilter = sb.ToString();
}
System.Data.SyntaxErrorException: '语法错误:'And' 运算符之后缺少操作数。'
这一直在工作,但我必须提供所有值(填写所有文本框)才能过滤:
public void EnableRowFiltering()
{
this.MainDataTable.DefaultView.RowFilter =
$"YRNRO LIKE '{this.YRNROSearchKey}*' " +
$"OR HAKUNIMI LIKE '{this.HAKUNIMISearchKey}*'" +
$"OR KONSERNI LIKE '{this.GROUPSearchKey}*'" +
$"OR LY LIKE '{this.BUSINESSIDSearchKey}*'";
}
我会选择 ReactiveExtensions(尤其是那些来自RxUI 的):
// written without IDE
var text1 = this.WhenAnyValue(x => x.YRNROSearchKey).Select(x => {
if(string.IsNullOrEmpty(x))
return null;
return $"YRNRO LIKE '%{x}%";
}); // get observable to monitor changes
var text2 = ...
var filterObservable = Observable.CombineLatest(
new []{text1, text2, text3} ,
(textParts) => {
return string.Join(" AND ", textParts.Where(x => !string.IsNullOrEmpty(x)));
}
)
.Throttle(TimeSpan.FromMilliseconds(80));
filterObservable.ObserveOnDispatcher().Subscribe(f => this.MainDataTable.DefaultView.RowFilter = f);
我真的很喜欢 Rx,所以我会这样做 - 也许您可以将其用作模板并以其他方式解决更改通知,但构建过滤器应该可以工作。
RxUI 还带有 DyanmicData - 用于数据操作的优秀库,它基本上是可观察的 LINQ
您必须处理AND
运算符。 您不能随时添加它,这取决于设置了多少条件(过滤器)。
假设定义一个名为int counter
的变量在开始时设置为零,并在每次设置过滤器时增加并在每次清理过滤器时减少,您的代码应更改为:
public void EnableRowFiltering()
{
StringBuilder sb = new StringBuilder();
var logicalOperator = counter > 0 ? " AND " : string.Empty;
if (YRNROSearchKey != string.Empty)
{
logicalOperator = counter++ > 0 ? " AND " : string.Empty;
sb.Append($"{logicalOperator}YRNRO LIKE '%{YRNROSearchKey}%'");
}
if (HAKUNIMISearchKey != string.Empty)
{
logicalOperator = counter++ > 0 ? " AND " : string.Empty;
sb.Append($"{logicalOperator}HAKUNIMI LIKE '%{HAKUNIMISearchKey}%'");
}
if (GROUPSearchKey != string.Empty)
{
logicalOperator = counter++ > 0 ? " AND " : string.Empty;
sb.Append($"{logicalOperator}KONSERNI LIKE '%{GROUPSearchKey}%'");
}
if (BUSINESSIDSearchKey != string.Empty)
{
logicalOperator = counter++ > 0 ? " AND " : string.Empty;
sb.Append($"{logicalOperator}LY LIKE '%{BUSINESSIDSearchKey}%'");
}
this.MainDataTable.DefaultView.RowFilter = sb.ToString();
}
最后一个解决方案是迄今为止最短的,所以我更喜欢它。
您只需将 OR 替换为 AND(我的错)。
public void EnableRowFiltering()
{
this.MainDataTable.DefaultView.RowFilter =
$"YRNRO LIKE '{this.YRNROSearchKey}*'" +
$"AND HAKUNIMI LIKE '{this.HAKUNIMISearchKey}*'" +
$"AND KONSERNI LIKE '{this.GROUPSearchKey}*'" +
$"AND LY LIKE '{this.BUSINESSIDSearchKey}*'";
}
第一个解决方案的表达式字符串有一个尾随AND
运算符,这会导致错误消息。 使用运算符为每个表达式(操作数)添加前缀将修复它。
请注意,必须删除表达式的前导%
才能使其成为“开头为”表达式。 具有前导%
和尾随%
(通配符运算符)将表示“包含”。
因为和空字符串变量会产生类似"Column LIKE '%'
的表达式,并且因为${null}
返回""
(空字符串),您可以缩短代码:
public void EnableRowFiltering()
{
StringBuilder sb = new StringBuilder();
sb.Append($"YRNRO LIKE '{this.YRNROSearchKey}%'");
sb.Append($"AND KONSERNI LIKE '{this.GROUPSearchKey}%'");
sb.Append($"AND LY LIKE '{this.BUSINESSIDSearchKey}%'");
this.MainDataTable.DefaultView.RowFilter = sb.ToString();
}
第二个解决方案的表达似乎是正确的,但不知何故分配变得混乱。 在定义过滤器表达式以修复它后分配过滤器表达式。
因为和空字符串变量会产生类似"Column LIKE '*'
的表达式,并且因为${null}
返回""
(空字符串),您可以缩短代码:
public void EnableRowFiltering()
{
string YRNRO = $"YRNRO LIKE '{this.YRNROSearchKey}*'";
string HAKUNIMI = $" AND HAKUNIMI LIKE '{this.HAKUNIMISearchKey}*'";
string GROUP = $" AND KONSERNI LIKE '{this.GROUPSearchKey}*'";
string BUSINESSID = $" AND LY LIKE '{this.BUSINESSIDSearchKey}*'";
this.MainDataTable.DefaultView.RowFilter = YRNRO + HAKUNIMI + GROUP + BUSINESSID;
}
三个方案都经过修复和改进后,都简化为基本相同的方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.