背景
由于最近项目中,客户指定界面组件要使用DevExpress第三方控件,因此就熟悉了DevExpress中常用控件的一些用法,现把一些重要控件的常见用法进行总结分享。
TreeList
在DevExpress中TreeList控件也是一个 很常用的控件,我的其中一个应用场景就是只读显示文件目录结构,因为Dev中的TreeList默认是显示列头和行线的,因此要通过设置只显示1列,并隐藏网格线,隐藏列头的方式实现普通TreeView的样式。先看一些最终的实现效果如下图:
实现的关键代码如下
1、DataTreeNodeTypes
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Wongoing.Gui.DataAnalysis.Common
{
public enum DataTreeNodeTypes
{
/// <summary>
/// 文件夹
/// </summary>
Folder = 0,
/// <summary>
/// 文件
/// </summary>
File = 1
}
}
2、DataTreeNode
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Wongoing.Gui.DataAnalysis.Common
{
[Serializable]
public class DataTreeNode
{
private string id;
private string parentId;
private string nodeText;
private string createDate;
private string fullPath;
private string taskFile;
private string barcode;
private DataTreeNodeTypes nodeType = DataTreeNodeTypes.Folder;
public string Id
{
get { return id; }
set { id = value; }
}
public string ParentId
{
get { return parentId; }
set { parentId = value; }
}
public string NodeText
{
get { return nodeText; }
set { nodeText = value; }
}
public string CreateDate
{
get { return createDate; }
set { createDate = value; }
}
public string FullPath
{
get { return fullPath; }
set { fullPath = value; }
}
public string TaskFile
{
get { return taskFile; }
set { taskFile = value; }
}
public string Barcode
{
get { return barcode; }
set { barcode = value; }
}
public DataTreeNodeTypes NodeType
{
get { return nodeType; }
set { nodeType = value; }
}
}
}
3、DataTreeListHelper(关键代码)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ICSharpCode.Core;
namespace Wongoing.Gui.DataAnalysis.Common
{
public class DataTreeListHelper
{
#region 事件定义
/// <summary>
/// 刷新数据事件
/// </summary>
public static event EventHandler OnRefreshData;
/// <summary>
/// 重新加载选中的数据时间
/// </summary>
public static event EventHandler OnReloadSelectData;
#endregion
#region 图标数组
public static System.Drawing.Image[] imgs = new System.Drawing.Image[] {
ICSharpCode.Core.ResourceService.GetImageResource("Icons_512x512_FolderOpen") as System.Drawing.Image,
ICSharpCode.Core.ResourceService.GetImageResource("Icons_512x512_FolderClose") as System.Drawing.Image,
ICSharpCode.Core.ResourceService.GetImageResource("Icons_512x512_DataNode") as System.Drawing.Image,
ICSharpCode.Core.ResourceService.GetImageResource("Icons_512x512_DataNodeSelect") as System.Drawing.Image
};
#endregion
#region 刷新树控件的数据
/// <summary>
/// 刷新树控件的数据
/// </summary>
/// <param name="treeList">树控件</param>
/// <param name="expandToLevel">刷新数据后默认展开的级别</param>
public static void RefreshTreeData(DevExpress.XtraTreeList.TreeList treeList, int expandToLevel)
{
string rootNodeId = Common.Global.AppConfig.TestDataDir;
string rootNodeText = ICSharpCode.Core.StringParser.Parse(ResourceService.GetString("Pad_DataTree_RootNodeText")); //"全部实验数据";
string fieldName = "NodeText";
string keyFieldName = "Id";
string parentFieldName = "ParentId";
List<DataTreeNode> data = new List<DataTreeNode>();
data = DataTreeListHelper.ParseDir(Common.Global.AppConfig.TestDataDir, data);
data.Add(new DataTreeNode() { Id = rootNodeId, ParentId = String.Empty, NodeText = rootNodeText, NodeType = DataTreeNodeTypes.Folder });
DataTreeListHelper.SetTreeListDataSource(treeList, data, fieldName, keyFieldName, parentFieldName);
treeList.ExpandToLevel(expandToLevel);
}
#endregion
#region 为树控件设置数据源
/// <summary>
/// 为树控件设置数据源
/// </summary>
/// <param name="treeList">树控件</param>
/// <param name="data">数据对象</param>
/// <param name="fieldName">显示的字段</param>
/// <param name="keyFieldName">键字段</param>
/// <param name="parentFieldName">父级键字段</param>
public static void SetTreeListDataSource(DevExpress.XtraTreeList.TreeList treeList, List<DataTreeNode> data, string fieldName, string keyFieldName, string parentFieldName)
{
#region 设置节点图标
System.Windows.Forms.ImageList imgList = new System.Windows.Forms.ImageList();
imgList.Images.AddRange(imgs);
treeList.SelectImageList = imgList;
//目录展开
treeList.AfterExpand -= treeList_AfterExpand;
treeList.AfterExpand += treeList_AfterExpand;
//目录折叠
treeList.AfterCollapse -= treeList_AfterCollapse;
treeList.AfterCollapse += treeList_AfterCollapse;
//数据节点单击,开启整行选中
treeList.MouseClick -= treeList_MouseClick;
treeList.MouseClick += treeList_MouseClick;
//数据节点双击选中
treeList.MouseDoubleClick -= treeList_MouseDoubleClick;
treeList.MouseDoubleClick += treeList_MouseDoubleClick;
//焦点离开事件
treeList.LostFocus -= treeList_LostFocus;
treeList.LostFocus += treeList_LostFocus;
#endregion
#region 设置列头、节点指示器面板、表格线样式
treeList.OptionsView.ShowColumns = false; //隐藏列标头
treeList.OptionsView.ShowIndicator = false; //隐藏节点指示器面板
treeList.OptionsView.ShowHorzLines = false; //隐藏水平表格线
treeList.OptionsView.ShowVertLines = false; //隐藏垂直表格线
treeList.OptionsView.ShowIndentAsRowStyle = false;
#endregion
#region 初始禁用单元格选中,禁用整行选中
treeList.OptionsView.ShowFocusedFrame = true; //设置显示焦点框
treeList.OptionsSelection.EnableAppearanceFocusedCell = false; //禁用单元格选中
treeList.OptionsSelection.EnableAppearanceFocusedRow = false; //禁用正行选中
//treeList.Appearance.FocusedRow.BackColor = System.Drawing.Color.Red; //设置焦点行背景色
#endregion
#region 设置TreeList的展开折叠按钮样式和树线样式
treeList.OptionsView.ShowButtons = true; //显示展开折叠按钮
treeList.LookAndFeel.UseDefaultLookAndFeel = false; //禁用默认外观与感觉
treeList.LookAndFeel.UseWindowsXPTheme = true; //使用WindowsXP主题
treeList.TreeLineStyle = DevExpress.XtraTreeList.LineStyle.Percent50; //设置树线的样式
#endregion
#region 添加单列
DevExpress.XtraTreeList.Columns.TreeListColumn colNode = new DevExpress.XtraTreeList.Columns.TreeListColumn();
colNode.Name = String.Format("col{0}", fieldName);
colNode.Caption = fieldName;
colNode.FieldName = fieldName;
colNode.VisibleIndex = 0;
colNode.Visible = true;
colNode.OptionsColumn.AllowEdit = false; //是否允许编辑
colNode.OptionsColumn.AllowMove = false; //是否允许移动
colNode.OptionsColumn.AllowMoveToCustomizationForm = false; //是否允许移动至自定义窗体
colNode.OptionsColumn.AllowSort = false; //是否允许排序
colNode.OptionsColumn.FixedWidth = false; //是否固定列宽
colNode.OptionsColumn.ReadOnly = true; //是否只读
colNode.OptionsColumn.ShowInCustomizationForm = true; //移除列后是否允许在自定义窗体中显示
treeList.Columns.Clear();
treeList.Columns.AddRange(new DevExpress.XtraTreeList.Columns.TreeListColumn[] { colNode });
#endregion
#region 绑定数据源
treeList.KeyFieldName = keyFieldName;
treeList.ParentFieldName = parentFieldName;
treeList.DataSource = data;
treeList.RefreshDataSource();
#endregion
#region 初始化图标
SetNodeImageIndex(treeList.Nodes.FirstOrDefault());
#endregion
}
/// <summary>
/// 焦点离开时,当前节点背景色整行选中
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void treeList_LostFocus(object sender, EventArgs e)
{
if (!String.IsNullOrEmpty(Global.Instance.CurrDataFile))
{
DevExpress.XtraTreeList.TreeList treeList = sender as DevExpress.XtraTreeList.TreeList;
if (treeList != null && treeList.Selection.Count == 1)
{
DevExpress.XtraTreeList.Nodes.TreeListNode node = treeList.FindNodeByKeyID(Global.Instance.CurrDataFile);
if (node != null)
{
if (!node.Selected)
{
treeList.OptionsSelection.EnableAppearanceFocusedRow = true; //启用整行选中
node.Selected = true;
Common.DataTreeListHelper.SetNodeImageIndex(treeList.Nodes.FirstOrDefault());
}
}
}
}
}
/// <summary>
/// 节点展开
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void treeList_AfterExpand(object sender, DevExpress.XtraTreeList.NodeEventArgs e)
{
e.Node.ImageIndex = 0;
e.Node.SelectImageIndex = e.Node.ImageIndex;
}
/// <summary>
/// 节点折叠
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void treeList_AfterCollapse(object sender, DevExpress.XtraTreeList.NodeEventArgs e)
{
e.Node.ImageIndex = 1;
e.Node.SelectImageIndex = e.Node.ImageIndex;
}
/// <summary>
/// 单击数据节点
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void treeList_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
{
DevExpress.XtraTreeList.TreeList treeList = sender as DevExpress.XtraTreeList.TreeList;
if (treeList != null && treeList.Selection.Count == 1)
{
object idValue = null;
string strIdValue = String.Empty;
DataTreeNode nodeData = null;
List<DataTreeNode> datasource = treeList.DataSource as List<DataTreeNode>;
if (datasource != null)
{
idValue = treeList.Selection[0].GetValue("Id");
strIdValue = idValue.ToString();
nodeData = datasource.Where<DataTreeNode>(p => p.Id == strIdValue).FirstOrDefault<DataTreeNode>();
if (nodeData != null)
{
if (nodeData.NodeType == DataTreeNodeTypes.File)
{
treeList.OptionsSelection.EnableAppearanceFocusedRow = true; //启用整行选中
return;
}
}
}
treeList.OptionsSelection.EnableAppearanceFocusedRow = false; //禁用整行选中
}
}
/// <summary>
/// 双击数据节点
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void treeList_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)
{
DevExpress.XtraTreeList.TreeList treeList = sender as DevExpress.XtraTreeList.TreeList;
if (treeList != null && treeList.Selection.Count == 1)
{
object idValue = null;
string strIdValue = String.Empty;
DataTreeNode nodeData = null;
List<DataTreeNode> datasource = treeList.DataSource as List<DataTreeNode>;
if (datasource != null)
{
idValue = treeList.Selection[0].GetValue("Id");
strIdValue = idValue.ToString();
nodeData = datasource.Where<DataTreeNode>(p => p.Id == strIdValue).FirstOrDefault<DataTreeNode>();
if (nodeData != null)
{
if (nodeData.NodeType == DataTreeNodeTypes.File)
{
SetNodeImageIndex(treeList.Nodes.FirstOrDefault());
Wongoing.PlugIn.Event.ParamEventArgs pea = new PlugIn.Event.ParamEventArgs(nodeData.Id);
TriggerReloadSelectDataEvent(sender, pea);
return;
}
}
}
}
}
#endregion
#region 递归设置节点图标
/// <summary>
/// 递归设置节点图标
/// </summary>
/// <param name="node">要设置图标的节点</param>
public static void SetNodeImageIndex(DevExpress.XtraTreeList.Nodes.TreeListNode node)
{
object idValue = null;
string strIdValue = String.Empty;
DataTreeNode nodeData = null;
List<DataTreeNode> data = node.TreeList.DataSource as List<DataTreeNode>;
if (data != null)
{
idValue = node.GetValue("Id");
strIdValue = idValue.ToString();
nodeData = data.Where<DataTreeNode>(p => p.Id == strIdValue).FirstOrDefault<DataTreeNode>();
if (nodeData != null)
{
if (nodeData.NodeType == DataTreeNodeTypes.Folder)
{
//文件夹
if (node.Expanded)
{
//展开
node.ImageIndex = 0;
node.SelectImageIndex = 0;
}
else
{
//折叠
node.ImageIndex = 1;
node.SelectImageIndex = 1;
}
}
else
{
//文件
if (!node.Selected)
{
//默认
node.ImageIndex = 2;
node.SelectImageIndex = 2;
}
else
{
//选中
node.ImageIndex = 3;
node.SelectImageIndex = 3;
}
}
}
foreach(DevExpress.XtraTreeList.Nodes.TreeListNode childNode in node.Nodes)
{
SetNodeImageIndex(childNode);
}
}
}
#endregion
#region 解析实验数据目录
/// <summary>
/// 解析实验数据目录
/// </summary>
/// <param name="dataRootDir">实验数据根目录</param>
/// <returns>返回数据节点列表对象</returns>
public static List<DataTreeNode> ParseDir(string dataRootDir, List<DataTreeNode> data)
{
if (data == null)
{
data = new List<DataTreeNode>();
}
if (!System.IO.Directory.Exists(dataRootDir))
{
return data;
}
DataTreeNode node = null;
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(dataRootDir);
System.IO.DirectoryInfo[] subDirs = dir.GetDirectories();
foreach(System.IO.DirectoryInfo subDir in subDirs)
{
node = new DataTreeNode();
node.Id = subDir.FullName;
node.ParentId = dir.FullName;
node.NodeText = subDir.Name;
node.CreateDate = String.Format("{0:yyyy-MM-dd HH:mm:ss}", subDir.CreationTime);
node.FullPath = subDir.FullName;
node.TaskFile = String.Empty; //任务文件名
node.NodeType = DataTreeNodeTypes.Folder;
data.Add(node);
ParseDir(subDir.FullName, data);
}
System.IO.FileInfo[] subFiles = dir.GetFiles();
foreach(System.IO.FileInfo subFile in subFiles)
{
//如果包含索引数据文件
if (subFile.Name.Contains(Global.INDEX_EXT))
{
node = new DataTreeNode();
node.Id = subFile.FullName.Replace(Global.INDEX_EXT, String.Empty);
node.ParentId = dir.FullName;
node.NodeText = subFile.Name.Replace(Global.INDEX_EXT, String.Empty);
node.CreateDate = String.Format("{0:yyyy-MM-dd HH:mm:ss}", subFile.CreationTime);
node.FullPath = subFile.FullName;
node.TaskFile = String.Empty; //任务文件名
node.NodeType = DataTreeNodeTypes.File;
data.Add(node);
}
}
return data;
}
#endregion
#region 触发事件
#region 触发刷新数据事件
/// <summary>
/// 触发刷新数据事件
/// </summary>
public static void TriggerRefreshDataEvent()
{
if (OnRefreshData != null)
{
OnRefreshData(null, System.EventArgs.Empty);
}
}
#endregion
#region 触发重新加载选中数据事件
public static void TriggerReloadSelectDataEvent(object sender, System.EventArgs e)
{
if (OnReloadSelectData != null)
{
OnReloadSelectData(sender, e);
}
}
#endregion
#endregion
}
}
4、窗体界面的调用代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Wongoing.Gui.DataAnalysis.Pad
{
using Wongoing.Gui.Dev.Pad;
public partial class DataTreePad : DefaultPadContent
{
private int defaultExpandLevel = 2;
public DataTreePad()
{
InitializeComponent();
}
private void DataTreePad_Load(object sender, EventArgs e)
{
Wongoing.Basic.LanguageHelper.LanguageChanged -= LanguageHelper_LanguageChanged;
Wongoing.Basic.LanguageHelper.LanguageChanged += LanguageHelper_LanguageChanged;
Common.DataTreeListHelper.OnRefreshData -= DataTreeListHelper_OnRefreshData;
Common.DataTreeListHelper.OnRefreshData += DataTreeListHelper_OnRefreshData;
Common.DataTreeListHelper.OnReloadSelectData -= DataTreeListHelper_OnReloadSelectData;
Common.DataTreeListHelper.OnReloadSelectData += DataTreeListHelper_OnReloadSelectData;
//刷新树控件数据
Common.DataTreeListHelper.RefreshTreeData(this.treeList1, this.defaultExpandLevel);
}
/// <summary>
/// 切换语言是刷新数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void LanguageHelper_LanguageChanged(object sender, EventArgs e)
{
Common.DataTreeListHelper.RefreshTreeData(this.treeList1, this.defaultExpandLevel);
}
/// <summary>
/// 刷新事件触发时刷新数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void DataTreeListHelper_OnRefreshData(object sender, EventArgs e)
{
Common.DataTreeListHelper.RefreshTreeData(this.treeList1, this.defaultExpandLevel);
if (!String.IsNullOrEmpty(Common.Global.Instance.CurrDataFile))
{
DevExpress.XtraTreeList.Nodes.TreeListNode node = this.treeList1.FindNodeByKeyID(Common.Global.Instance.CurrDataFile);
if (node != null)
{
if (!node.Selected)
{
this.treeList1.OptionsSelection.EnableAppearanceFocusedRow = true; //启用整行选中
node.Selected = true;
Common.DataTreeListHelper.SetNodeImageIndex(this.treeList1.Nodes.FirstOrDefault());
}
}
}
}
/// <summary>
/// 重新加载选择数据后,如果对应的文件节点没有选中,则进行选中,主要是对应查询对话框的选择
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DataTreeListHelper_OnReloadSelectData(object sender, EventArgs e)
{
if (e is Wongoing.PlugIn.Event.ParamEventArgs)
{
Wongoing.PlugIn.Event.ParamEventArgs pea = e as Wongoing.PlugIn.Event.ParamEventArgs;
string id = pea.Parameter as string;
DevExpress.XtraTreeList.Nodes.TreeListNode node = this.treeList1.FindNodeByKeyID(id);
if (node != null)
{
if (!node.Selected)
{
node.Selected = true;
Common.DataTreeListHelper.SetNodeImageIndex(this.treeList1.Nodes.FirstOrDefault());
}
}
}
}
}
}