在一些字典绑定中往往为了方便展示详细数据需要把一些结构树展现在树列表TreeList控件中或者下拉列表的树形控件TreeListLookUpEdit控件中为了快速的处理数据的绑定操作比较每次使用涉及太多细节的操作我们可以把相关的数据绑定操作放在一些辅助类的扩展函数中进行处理这样可以更方便的更简洁的处理数据绑定操作本文将介绍TreeList控件和TreeListLookUpEdit控件在扩展函数中的处理操作。PS给大家推荐一个C#开发可以用到的界面组件——DevExpress WinForms它能完美构建流畅、美观且易于使用的应用程序无论是Office风格的界面还是分析处理大批量的业务数据它都能轻松胜任DevExpress新旧版本帮助文档下载欢迎进QQ qun获取169725316TreeList控件的绑定操作TreeList本身就是一个树形数据的展示控件可以展示常规的二维表也可以展示具有嵌套关系的二维表数据源可以是多种方式的支持Datable的数据源的嵌套展示。单个列信息的树形列表展示界面效果类似GridView的嵌套列表展示的TreeList界面效果这些界面都比较常见也是我们经常碰到的处理效果但是TreeList的界面设置有很多特性如果每次拷贝这些代码需要很多也不便于维护因此我们建立一些扩展函数来处理界面元素的绑定就非常必要。本文介绍基于TreeList和TreeListLookUpEdit控件的绑定即可。两个类型控件的数据源都可以是DataTable类型也可以是IList集合类型如下所示是基于SQLSugar开发框架返回的数据结构是IList类型的。所以一般树形列表的绑定操作提供一个方法来获取数据并绑定即可。/// summary /// 绑定树的数据源 /// /summary private async void BindTree() { var list await BLLFactoryIDictTypeService.Instance.GetAllAsync(); this.tree.DataSource list?.Items; this.tree.ExpandAll(); }如果使用原生代码初始化树列表那么代码如下所示。//使用原生代码处理 //添加显示列 this.tree.Columns.Add(new TreeListColumn{ FieldName Id, Caption ID});//增加一个隐藏的字段存储需要的ID this.tree.Columns.Add(new TreeListColumn{ FieldName Name, Caption 字典类型名称, Width160, VisibleIndex 0}); //设置树控件的层次关系及属性 tree.KeyFieldName Id; tree.ParentFieldName PID; this.tree.OptionsBehavior.Editable false; this.tree.OptionsView.ShowColumns false; this.tree.OptionsView.ShowCheckBoxes false; this.tree.OptionsView.EnableAppearanceOddRow true; this.tree.OptionsView.EnableAppearanceEvenRow true;而实现查询过滤的操作还需要另外处理代码我们看看大概的代码如下。/// summary /// 实现树节点的过滤查询 /// /summary private void InitSearchControl() { this.searchControl1.Client this.tree; this.tree.FilterNode (object sender, FilterNodeEventArgs e) { if (tree.DataSource null) return; string nodeText e.Node.GetDisplayText(Name);//参数填写FieldName if (string.IsNullOrWhiteSpace(nodeText)) return; bool isExist nodeText.IndexOf(searchControl1.Text, StringComparison.OrdinalIgnoreCase) 0; if (isExist) { var node e.Node.ParentNode; while (node ! null) { if (!node.Visible) { node.Visible true; node node.ParentNode; } else break; } } e.Node.Visible isExist; e.Handled true; }; }这些是比较常见的操作我们把它封装为扩展函数然后根据特性传入对应参数实现即可。最后简单的三行代码来简单处理可以达到同样的效果就可以了。//控件扩展函数封装处理 this.tree.CreateColumn(Name, 字典类型名称, 160, true); this.tree.InitTree(Id, PID, -1, false, false); this.tree.InitSearchControl(this.searchControl1, Name);我们扩展方法放在一个单独的文件中标注为静态类即可。/// summary /// TreeList控件的扩展函数 /// /summary public static class TreeList_Extension其中提供几个对TreeList 常见的封装处理方法就可以了。对于一些不常见的属性我们保留它即可如下界面代码是对TreeList绑定展示多个列的处理操作。/// summary /// 初始化TreeList控件,展现嵌套的列表。 /// /summary private void InitControl() { this.tree.Columns.Clear();//控件扩展函数封装处理 this.tree.CreateColumn(Name, 机构名称, 160, true); this.tree.CreateColumn(HandNo, 机构编码, 80, true); this.tree.CreateColumn(Category, 机构分类, 80, true); this.tree.CreateColumn(Address, 机构地址, 160, true); this.tree.CreateColumn(InnerPhone, 内线电话, 80, true); this.tree.CreateColumn(OuterPhone, 外线电话, 80, true); this.tree.CreateColumn(SortCode, 排序码, 80, true); this.tree.InitTree(Id, PID, null, true, true); this.tree.OptionsView.RowImagesShowMode RowImagesShowMode.InCell;//紧凑型图标 this.tree.ExpandAll(); // 列过滤处理 this.tree.OptionsView.ShowAutoFilterRow true;//显示过滤行 this.tree.OptionsBehavior.EnableFiltering true;//开启过滤功能 //初始化树节点选择事件 this.tree.FocusedNodeChanged delegate (object sender, FocusedNodeChangedEventArgs e) { this.FocusedNodeChanged(); }; //树节点双击处理事件 this.tree.DoubleClick (s, e) { if (this.tree.FocusedNode ! null) { string ID string.Concat(this.tree.FocusedNode.GetValue(Id)); MessageDxUtil.ShowTips(Id ID); } }; //编辑记录失去焦点后校验处理 this.tree.ValidateNode (s, e) { Console.WriteLine(this.tree.FocusedNode.GetValue(Name)); }; }实现类似GridView的嵌套列表展示的TreeList界面效果如下所示。TreeListLookUpEdit控件绑定操作在一些参考的列表中我们往往需要展示更丰富一点的列表内容如下所示。如果有嵌套列表的展示嵌套列表的处理对于下拉的树形列表虽然这个控件比TreeList更复杂一些它是下拉列表和TreeList的整合体不过我们也可以用类似的扩展函数方法来简单的实现数据的绑定展示。如对于常规的数据绑定我们大概的代码如下所示。//TreeListLookupEdit数据绑定 //this.txtProjectList3.Properties.TreeList.OptionsView.ShowCheckBoxes true; this.txtProjectList3.Properties.DataSource list; this.txtProjectList3.Properties.ValueMember Value; this.txtProjectList3.Properties.DisplayMember Text; this.txtProjectList3.Properties.TreeList.Columns.Clear(); for (int i 0; i columns.Count; i) { this.txtProjectList3.Properties.TreeList.CreateColumn(columns[i].FieldName, columns[i].Caption, columns[i].Width, true); } this.txtProjectList3.Properties.TreeList.InitTree(null, null, null, true, true); this.txtProjectList3.Properties.ImmediatePopup true; this.txtProjectList3.Properties.TextEditStyle TextEditStyles.Standard; this.txtProjectList3.Properties.PopupWidthMode DevExpress.XtraEditors.PopupWidthMode.ContentWidth; this.txtProjectList3.Properties.PopupFormSize new System.Drawing.Size(this.txtProjectList3.Width, 300); this.txtProjectList3.Properties.TreeList.IndicatorWidth 40; this.txtProjectList3.Properties.TreeList.CustomDrawNodeIndicator (s, ee) { if (ee.IsNodeIndicator) { var index ee.Node.TreeList.GetVisibleIndexByNode(ee.Node); ee.Info.DisplayText (index 1).ToString(); } };对于常规的列表绑定我们可以用简单的一个扩展函数实现如下所示。//常规类别绑定 this.txtProjectList4.BindDictItems(list, Text, Value, true, columns.ToArray());就可以实现常规的界面效果处理。对于树形列表我们需要设置属性的ID和PID以及一些显示的列属性那么也可以增加更多的参数来实现。var dictTypeColumns new ListLookUpColumnInfo() { new LookUpColumnInfo(Id, Id), new LookUpColumnInfo(Name, 字典类别名称) }; treeListLookUp.BindDictItems(result.Items, Name, Id, true, false, Id, PID, null, true, true, true, false, dictTypeColumns.ToArray());因此嵌套列表就可以正常的展示出层次关系了。因此我们把扩展方法放到静态类里面就可以了方法封装如下所示/// summary /// 绑定TreeListLookUpEdit控件的数据源(完整版 /// /summary /// param namelookup控件对象/param /// param namedataSource数据源/param /// param namedisplayMember显示字段/param /// param namevalueMember值字段/param /// param nameshowRowIndicator是否显示序号/param /// param nameshowCheckbox是否显示复选框/param /// param namekeyFieldName设置父子递归关系字段-子字段不指定则使用valueMember/param /// param nameparentFieldName设置父子递归关系字段-父字段不指定则不嵌套展示/param /// param namerootValue根节点的值/param /// param nameeditable树节点是否可以编辑/param /// param nameshowColumnHeader是否显示列头/param /// param nameoddEvenRowColor是否奇偶行不同颜色/param /// param nameallowDrop是否运行拖动列/param /// param namelookUpColumnInfos显示的列/param /// returns/returns public static object BindDictItems(this TreeListLookUpEdit lookup, object dataSource, string displayMember, string valueMember, bool showRowIndicator true, bool showCheckbox false, string keyFieldName null, string parentFieldName null, string rootValue null, bool editable true, bool showColumnHeader false, bool oddEvenRowColor true, bool allowDrop false, params LookUpColumnInfo[] lookUpColumnInfos) { lookup.Properties.DataSource dataSource; lookup.Properties.DisplayMember displayMember; lookup.Properties.ValueMember valueMember; lookup.Properties.TreeList.OptionsView.ShowCheckBoxes showCheckbox; lookup.Properties.TreeList.Columns.Clear(); for (int i 0; i lookUpColumnInfos.Length; i) { lookup.Properties.TreeList.CreateColumn(lookUpColumnInfos[i].FieldName, lookUpColumnInfos[i].Caption, lookUpColumnInfos[i].Width, true); } //初始化树的样式和特性 //keyFieldName !string.IsNullOrWhiteSpace(keyFieldName) ? keyFieldName : valueMember;//如果不指定采用valueMember lookup.Properties.TreeList.InitTree(keyFieldName, parentFieldName, rootValue, editable, showColumnHeader, oddEvenRowColor, allowDrop); lookup.Properties.PopupFormSize new System.Drawing.Size(lookup.Width, 300); lookup.Properties.ImmediatePopup true; lookup.Properties.TextEditStyle TextEditStyles.Standard; if (showRowIndicator) { lookup.Properties.TreeList.IndicatorWidth 40; //重写序号显示默认不显示数值 lookup.Properties.TreeList.CustomDrawNodeIndicator (s, ee) { if (ee.IsNodeIndicator) { var index ee.Node.TreeList.GetVisibleIndexByNode(ee.Node); ee.Info.DisplayText (index 1).ToString(); } }; } return dataSource; }通过扩展方法的方式可以简化界面的处理代码同时利于我们在项目开发的时候快速的实现相关的效果而不需要过多的中断查找相关的界面控件属性。本文转载自博客园 - 伍华聪