1、TreeList控件的绑定操作
TreeList本身就是一个树形数据的展示控件,可以展示常规的二维表,也可以展示具有嵌套关系的二维表,数据源可以是多种方式的,支持Datable的数据源的嵌套展示。
/// <summary> /// 绑定树的数据源 /// </summary> private async void BindTree( { var list = await BLLFactory<IDictTypeService>.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= "字典类型名称", Width=160, 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 常见的封装处理方法就可以了。
/// <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界面效果如下所示。
2、TreeListLookUpEdit控件绑定操作
在一些参考的列表中,我们往往需要展示更丰富一点的列表内容,如下所示。
如对于常规的数据绑定,我们大概的代码如下所示。
//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(;
就可以实现常规的界面效果处理。
var dictTypeColumns = new List<LookUpColumnInfo>( { 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 name="lookup">控件对象</param> /// <param name="dataSource">数据源</param> /// <param name="displayMember">显示字段</param> /// <param name="valueMember">值字段</param> /// <param name="showRowIndicator">是否显示序号</param> /// <param name="showCheckbox">是否显示复选框</param> /// <param name="keyFieldName">设置父子递归关系字段-子字段,不指定则使用valueMember</param> /// <param name="parentFieldName">设置父子递归关系字段-父字段,不指定则不嵌套展示</param> /// <param name="rootValue">根节点的值</param> /// <param name="editable">树节点是否可以编辑</param> /// <param name="showColumnHeader">是否显示列头</param> /// <param name="oddEvenRowColor">是否奇偶行不同颜色</param> /// <param name="allowDrop">是否运行拖动列</param> /// <param name="lookUpColumnInfos">显示的列</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; }
通过扩展方法的方式,可以简化界面的处理代码,同时利于我们在项目开发的时候,快速的实现相关的效果,而不需要过多的中断查找相关的界面控件属性。
《在Winform开发中,我们使用的几种下拉列表展示字典数据的方式》
《在各种开发项目中使用公用类库的扩展方法,通过上下文方式快速调用处理函数》
编程笔记 » 使用扩展函数方式,在Winform界面中快捷的绑定树形列表TreeList控件和TreeListLookUpEdit控件