由于DevExpress TreeList自带的过滤方式有缺陷,当过滤到父级节点时候,子节点只要不满足条件就不显示,有时候我们并不想这样,虽然dev最近的版本解决了当过滤到子节点的时候显示其父级节点的BUG(将treeList1.OptionsFilter.FilterMode = DevExpress.XtraTreeList.FilterMode.Extended;),但是过滤到父级显示其子级问题却没有解决,所以无奈的只能自定义过滤规则。该规则包括过滤到父级显示子级,和过滤到子级显示父级。操作方式很简单,只需注册ColumnFilterChanged事件,以下方法可以根据个人喜好用公共方法调用
效果图如下:
#region 自定义treelist过滤方式
private void tree_ColumnFilterChanged(object sender, EventArgs e)
{
TreeList tree = sender as TreeList;
if (tree.ActiveFilterInfo != null)//FilterPopup,FilterRow两种过滤方式
{
string col = string.Empty;
string newKey = string.Empty;
var criteria = tree.ActiveFilterInfo.FilterCriteria;
if (criteria is DevExpress.Data.Filtering.FunctionOperator)//FilterRow 输入
{
var operands = ((DevExpress.Data.Filtering.FunctionOperator)criteria).Operands;
col = ((DevExpress.Data.Filtering.OperandProperty)(operands[0])).PropertyName;
newKey = ((DevExpress.Data.Filtering.OperandValue)(operands[1])).Value.ToString();
FilterNodeOperation operation = new FilterNodeOperation(tree.Columns[col], newKey);
tree.NodesIterator.DoOperation(operation);
}
else if (criteria is DevExpress.Data.Filtering.BinaryOperator)//FilterPopup 单选
{
var leftOperand = ((DevExpress.Data.Filtering.BinaryOperator)criteria).LeftOperand;
col = ((DevExpress.Data.Filtering.OperandProperty)leftOperand).PropertyName;
newKey = ((DevExpress.Data.Filtering.OperandValue)((DevExpress.Data.Filtering.BinaryOperator)criteria).RightOperand).Value.ToString();
FilterNodeOperation operation = new FilterNodeOperation(tree.Columns[ col], newKey,false);
tree.NodesIterator.DoOperation(operation);
}
else if (criteria is DevExpress.Data.Filtering.InOperator)//FilterPopupCheckList 多选过滤
{
var leftOperand = ((DevExpress.Data.Filtering.InOperator)criteria).LeftOperand;
col = ((DevExpress.Data.Filtering.OperandProperty)leftOperand).PropertyName;
var operands = ((DevExpress.Data.Filtering.InOperator)criteria).Operands;
string [] newKeys = operands.Cast().Select(p=>p.Value.ToString()).ToArray();
FilterNodeOperation operation = new FilterNodeOperation(tree.Columns[ col], newKeys);
tree.NodesIterator.DoOperation(operation);
}
}
else //Find Panel 过滤
{
string newKey = tree.FindFilterText;
FilterNodeOperation operation = new FilterNodeOperation((!System.String.IsNullOrEmpty(newKey)) ? newKey : "");
tree.NodesIterator.DoOperation(operation);
}
}
///
/// 过滤节点操作
///
public class FilterNodeOperation : DevExpress.XtraTreeList.Nodes.Operations.TreeListOperation
{
string pattern;
DevExpress.XtraTreeList.Columns.TreeListColumn col;
string[] patterns;
bool byEdit;
public FilterNodeOperation(string _pattern,bool _byEdit=true)
{ pattern = _pattern;byEdit = _byEdit; }
public FilterNodeOperation(DevExpress.XtraTreeList.Columns.TreeListColumn _col, string _pattern, bool _byEdit = true)
{ pattern = _pattern; col = _col; byEdit = _byEdit; }
public FilterNodeOperation(DevExpress.XtraTreeList.Columns.TreeListColumn _col,string[] _patterns)
{ patterns = _patterns;pattern = "null";col = _col; byEdit = true;
}
public override void Execute(TreeListNode node)
{
if (string.IsNullOrEmpty(pattern)&&byEdit)
{ node.Visible = true; return; }
bool contain = false;
if (col==null)
contain = NodeContainsPattern(node, pattern);
else
{
if (patterns!=null)
{
contain = NodeContainsPattern(col, node, patterns);
}else
contain = NodeContainsPattern(col, node, pattern);
}
if (contain)
{
node.Visible = true;
if (node.ParentNode != null)
node.ParentNode.Visible = true;
if (node.HasChildren)
node.Nodes.ToList().ForEach(p => p.Visible = true);
}
else
{
if (node.ParentNode != null ? node.Visible : false)
node.Visible = true;
else
node.Visible = false;
}
}
bool NodeContainsPattern(DevExpress.XtraTreeList.Columns.TreeListColumn _col, TreeListNode node, string pattern)
{
string value = "";
if (_col.FilterMode == ColumnFilterMode.DisplayText)
value = node.GetDisplayText(_col);
else
value= node.GetValue(_col)?.ToString().ToUpper();
if (string.IsNullOrEmpty(value))
{
if (pattern == value)
return true;
else
return false;
} else if (string.IsNullOrEmpty(pattern))
{
if (pattern == value)
return true;
else
return false;
}
else
{
if (value.Contains(pattern.ToUpper()) || pattern.ToUpper().Contains(value) || value.Equals(pattern))
return true;
}
return false;
}
bool NodeContainsPattern(TreeListNode node, string pattern)
{
string value = "";
foreach (DevExpress.XtraTreeList.Columns.TreeListColumn col in node.TreeList.Columns)
{
if (!col.Visible)
continue;
if(col.FilterMode== ColumnFilterMode.DisplayText)
{
value = node.GetDisplayText(col).ToUpper();
}else
value = node.GetValue(col)?.ToString().ToUpper();
if (string.IsNullOrEmpty(value))
{
if (value == pattern)
return true;
else
return false;
}
else
{
if (value.Contains(pattern.ToUpper()) || pattern.ToUpper().Contains(value) )
return true;
}
}
return false;
}
bool NodeContainsPattern(DevExpress.XtraTreeList.Columns.TreeListColumn _col, TreeListNode node, string[] patterns)
{
string value = "";
if ( _col.FilterMode == ColumnFilterMode.DisplayText)
{
value = node.GetDisplayText(col).ToUpper();
}
else
value = node.GetValue(col)?.ToString().ToUpper();
if ( patterns.ToList().Exists(p => p.Equals(value) || value.Equals(p)))
return true;
return false;
}
}
#endregion