![](/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.