使用DevExpress的TreeList顯示本磁盤下文件目錄並在樹節點上右鍵實現刪除與添加文件。node
自定義右鍵效果工具
首先在包含Treelist的窗體的load方法中對treelist進行初始化this
Common.DataTreeListHelper.RefreshTreeData(this.treeList1, 2);
其中this.treeList1就是當前窗體的treelist對象spa
而後第二個參數是默認展開級別。.net
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); }
在上面方法中新建根節點,根節點的Id就是要顯示的目錄,在配置文件中讀取。
根節點的顯示文本就是顯示「所有實驗數據」,從配置文件中獲取。設計
而後調用工具類將目錄結構轉換成帶父子級關係的節點的list,而後再將根節點添加到list。code
而後調用設置treeList數據源的方法。orm
在上面方法中存取節點信息的DataTreeNode對象
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; } } }
在上面方法中將目錄結構轉換爲節點list的方法blog
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(); return data; }
經過遞歸將上面傳遞過來的目錄下的結構構形成節點的list並返回。
經過解析實驗目錄的方法返回list後再調用刷新treelist節點的方法
SetTreeListDataSource
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.DataSource = null; treeList.KeyFieldName = keyFieldName; treeList.ParentFieldName = parentFieldName; treeList.DataSource = data; treeList.RefreshDataSource(); #endregion #region 初始化圖標 SetNodeImageIndex(treeList.Nodes.FirstOrDefault()); #endregion }
若是不考慮根據文件仍是文件夾設置節點圖標和綁定其餘雙擊事件等。
直接關注鼠標單擊事件的綁定和下面初始化樣式的設置。
在單擊鼠標節點綁定的方法中
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; //啓用整行選中 if (e.Button == System.Windows.Forms.MouseButtons.Right) { System.Windows.Forms.ContextMenu ctxMenu = new System.Windows.Forms.ContextMenu(); #region 右鍵彈出上下文菜單 - 刪除數據文件 System.Windows.Forms.MenuItem mnuDelete = new System.Windows.Forms.MenuItem(); mnuDelete.Text = "刪除"; mnuDelete.Click += delegate(object s, EventArgs ea) { DialogResult dialogResult = DevExpress.XtraEditors.XtraMessageBox.Show(String.Format("肯定要刪除此實驗數據嗎[{0}]?\r\n刪 除後沒法恢復!", nodeData.Id), "標題", System.Windows.Forms.MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (dialogResult == DialogResult.Yes) { try { string fileName = String.Empty; #region 刪除數據文件 fileName = String.Format("{0}{1}", nodeData.Id, Global.MAIN_EXT); if (System.IO.File.Exists(fileName)) { System.IO.File.Delete(fileName); } #endregion #region 刪除對應的樹節點 DevExpress.XtraTreeList.Nodes.TreeListNode selectedNode = treeList.FindNodeByKeyID(nodeData.Id); if (selectedNode != null) { selectedNode.ParentNode.Nodes.Remove(selectedNode); } #endregion treeList.OptionsSelection.EnableAppearanceFocusedRow = false; //禁用整行選中 } catch(Exception ex) { ICSharpCode.Core.LoggingService<DataTreeListHelper>.Error("刪除實驗數據異常:" + ex.Message, ex); DevExpress.XtraEditors.XtraMessageBox.Show("刪除實驗數據異常:" + ex.Message, "標題", MessageBoxButtons.OK, MessageBoxIcon.Error); } } }; ctxMenu.MenuItems.Add(mnuDelete); #endregion #region 右鍵彈出上下文菜單 - 重命名數據文件 System.Windows.Forms.MenuItem mnuReName = new System.Windows.Forms.MenuItem(); mnuReName.Text = "重命名"; mnuReName.Click += delegate(object s, EventArgs ea) { //獲取當前文件名 string oldName = Path.GetFileNameWithoutExtension(strIdValue); Dialog.FrmReName frmReName = new FrmReName(oldName); frmReName.StartPosition = FormStartPosition.CenterScreen; DialogResult result = frmReName.ShowDialog(); if (result == DialogResult.OK) { //刷入框新設置的文件名 string newName = frmReName.FileName; //獲取原來路徑 string filePath = Path.GetDirectoryName(strIdValue); //使用原來路徑加 + 新文件名 結合成新文件路徑 string newFilePath = Path.Combine(filePath, newName); DialogResult dialogResult = DevExpress.XtraEditors.XtraMessageBox.Show(String.Format("肯定要將實驗數據[{0}]重命名爲 [{1}]嗎?", nodeData.Id, newName), "標題", System.Windows.Forms.MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (dialogResult == DialogResult.Yes) { try { string fileName = String.Empty; string newFileName = String.Empty; #region 重命名主通道數據文件 fileName = String.Format("{0}{1}", nodeData.Id, Global.MAIN_EXT); newFileName = String.Format("{0}{1}", newFilePath, Global.MAIN_EXT); if (System.IO.File.Exists(fileName)) { FileInfo fi = new FileInfo(fileName); fi.MoveTo(newFileName); } #endregion //刷新樹 Common.DataTreeListHelper.TriggerRefreshDataEvent(); XtraMessageBox.Show("重命名成功"); treeList.OptionsSelection.EnableAppearanceFocusedRow = false; //禁用整行選中 } catch (Exception ex) { ICSharpCode.Core.LoggingService<DataTreeListHelper>.Error("刪除實驗數據異常:" + ex.Message, ex); DevExpress.XtraEditors.XtraMessageBox.Show("刪除實驗數據異常:" + ex.Message, "標題", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } }; ctxMenu.MenuItems.Add(mnuReName); #endregion #endregion ctxMenu.Show(treeList, new System.Drawing.Point(e.X, e.Y)); } return; } } } treeList.OptionsSelection.EnableAppearanceFocusedRow = false; //禁用整行選中 } }
其中在進行重命名時須要彈出一個窗體
具體實現參照:
Winform巧用窗體設計完成彈窗數值綁定-以重命名彈窗爲例:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103155532