我遇到了完全相同的问题。这是一个解决方案。它可能不是最优雅的,但它确实有效。
在 Datagrid 的 Loaded 事件中,找到 TextBox 元素。你可以使用写成here的算法。您可以通过检查它们的名称来缩小元素范围,这将是“PART_TextBoxFilter”,它们的类型将是 DataGridFilterLibrary.Support.DelayTextBox(它是 TextBox 的后代)。它仍然会发现比您需要的更多,您可以检查它们的绑定路径是否不为空(这不是以下示例的一部分)。关键是要在它们上挂一个 KeyDown 事件处理程序:
void dgFilter_Loaded(object sender, RoutedEventArgs e)
{
foreach (TextBox tb in FindVisualChildren<TextBox>(sender as DataGrid))
{
if (tb != null && tb.Name == "PART_TextBoxFilter")
{
tb.KeyUp += new KeyEventHandler(tbDelayTextBox_KeyUp);
}
}
}
在事件处理方法中,可以达到过滤器值,但这还不够。绑定路径的名称也必须保存,否则您将不知道它应该过滤哪一列。此外,您的窗口中可以有多个数据网格,因此数据网格的名称也很重要。
我使用字典来保存过滤器。
Dictionary<string,string> filterValues;
void tbDelayTextBox_KeyUp(object sender, KeyEventArgs e)
{
string dgName;
var bindingPath = DelayTextBoxBindingPath(sender as DataGridFilterLibrary.Support.DelayTextBox, out dgName);
if (!String.IsNullOrEmpty(bindingPath))
{
var key = dgName + "_" + bindingPath;
if (filterValues.ContainsKey(key))
{
filterValues[key] = ((TextBox)sender).Text;
}
else
{
filterValues.Add(key, ((TextBox)sender).Text);
}
}
}
这里是获取绑定路径和数据网格名称的方法:
string DelayTextBoxBindingPath(DataGridFilterLibrary.Support.DelayTextBox __dtb, out string datagridName)
{
datagridName = String.Empty;
var result = String.Empty;
if (__dtb != null)
{
BindingExpression be = __dtb.GetBindingExpression(TextBox.TextProperty) as BindingExpression;
if (be != null)
{
var dgcf = be.DataItem as DataGridFilterLibrary.DataGridColumnFilter;
if (dgcf != null && dgcf.FilterCurrentData != null)
{
result = dgcf.FilterCurrentData.ValuePropertyBindingPath;
datagridName = dgcf.DataGrid.Name;
}
}
}
return result;
}
要保存/加载过滤器,您可以分别使用窗口的 OnClosing 和 Datagrid 的 Loaded 事件(上图)。
希望这会有所帮助。