DXP TreeList 目錄樹

来源:https://www.cnblogs.com/ycit/archive/2023/08/04/17604994.html
-Advertisement-
Play Games

# DXP TreeList 目錄樹 ## 1.需求背景 需要一個支持`勾選`,`拖動節點`,`保存各節點順序`的目錄樹。 ![image](https://jsd.cdn.zzko.cn/gh/YuanjunXu/Images@main/src/image.3wqa9fpk8xo0.jpg) ## ...


DXP TreeList 目錄樹

1.需求背景

需要一個支持勾選拖動節點保存各節點順序的目錄樹。

image

2.創建目錄樹

treeList控制項中添加兩個colunm 用來顯示綁定數據顯示值。

image

接下來對treeList的屬性進行設置

            // 設置列不顯示
            treeList.OptionsView.ShowColumns = false;
            // 設置序號列不顯示
            treeList.OptionsView.ShowIndicator = false;
            // 設置垂直線不顯示
            treeList.OptionsView.ShowVertLines = false;
            // 設置水平線不顯示
            treeList.OptionsView.ShowHorzLines = false;
            // 設置焦點框為行焦點
            treeList.OptionsView.FocusRectStyle = DevExpress.XtraTreeList.DrawFocusRectStyle.RowFocus;
            // 隱藏第一列(數據列)
            treeListColumn1.Visible = false;
            // 設置不可編輯
            treeList.OptionsBehavior.Editable = false;
            // 設置顯示覆選框
            treeList.OptionsView.ShowCheckBoxes = true;
            // 設置勾選父節點,子節點自動全選
            treeList.OptionsBehavior.AllowRecursiveNodeChecking = true;


添加節點

        private TreeListNode AppendNode(PrjTableNode node, int pid)
        {
            TreeListNode treeListNode = null;
            Action<PrjTableNode, int> ac = (arg1, arg2) =>
             {
                 treeListNode = treeList.AppendNode(new object[] { node, node.Alias }, pid, 0, 0, 0);
             };
            var tt = treeList.Invoke(ac, new object[] { node, pid });
            SetNodeCheckState(treeListNode);
            return treeListNode;
        }

主要用到treeList.AppendNode()方法,方法定義如下

 AppendNode(object nodeData, int parentNodeId, int imageIndex, int selectImageIndex, int stateImageIndex)
  • nodeData : object 類型的參數,這裡傳入object[]數組對象,數組對應treeList的列,這裡第一列是數據,第二列用來顯示,因此需要將第一列隱藏。
  • parentNodeId :父節點ID
  • imageIndex : 節點圖標索引,這裡沒有圖標就給任意一個數字
  • selectImageIndex : 節點被選擇後顯示的圖標索引
  • stateImageIndex : 狀態圖標索引

此時目錄樹就創建好了。

2.1 設置目錄樹選中節點的背景色

添加CustomDrawNodeCell事件

            // 設置行背景色
            treeList.CustomDrawNodeCell -= TreeList_CustomDrawNodeCell;
            treeList.CustomDrawNodeCell += TreeList_CustomDrawNodeCell;

設置顏色

        private void TreeList_CustomDrawNodeCell(object sender, DevExpress.XtraTreeList.CustomDrawNodeCellEventArgs e)
        {
            if (e.Node.Selected)
            {
                e.Appearance.BackColor = Color.FromArgb(192, 192, 255);
            }
        }

2.2 控制目錄樹節點的勾選框是否顯示

添加CustomDrawNodeCheckBox事件

            // 控制覆選框顯隱
            treeList.CustomDrawNodeCheckBox -= TreeList_CustomDrawNodeCheckBox;
            treeList.CustomDrawNodeCheckBox += TreeList_CustomDrawNodeCheckBox;
        private void TreeList_CustomDrawNodeCheckBox(object sender, DevExpress.XtraTreeList.CustomDrawNodeCheckBoxEventArgs e)
        {
            // 滿足邏輯條件的 ,將 e.Handled = true 即可
            if ((e.Node.GetValue(treeListColumn1) as PrjTableNode)?.Type == ConstClass1.PRJ_TYPE_ID)
            {
                //e.Handled = true;
            }
        }

2.3 節點拖拽

這裡的需求是只允許同級節點內部拖動,也不允許拖動到節點子集。

設置屬性OptionsDragAndDrop.DragNodesMode = DragNodesMode.Single

添加DragOver,DragDropAfterDragNode事件

            // 設置節點拖拽
            treeList.OptionsDragAndDrop.DragNodesMode = DragNodesMode.Single;
		   // 處理拖動時的邏輯 
            treeList.DragOver -= TreeList_DragOver;
            treeList.DragOver += TreeList_DragOver;
		   // 處理拖動結束時的邏輯 
            treeList.DragDrop -= TreeList_DragDrop;
            treeList.DragDrop += TreeList_DragDrop;
		   // 處理拖動後的邏輯 
            treeList.AfterDragNode -= TreeList_AfterDragNode;
            treeList.AfterDragNode += TreeList_AfterDragNode;

DragOver 用來處理拖動時的邏輯

當有節點需要禁止拖動時,滿足邏輯時,設置 e.Effect = DragDropEffects.None;即可

       private void TreeList_DragOver(object sender, DragEventArgs e)
        {
            var currNode = treeList.FocusedNode;
            var curNodeData = currNode.GetValue(treeListColumn1) as PrjTableNode;
            if (curNodeData == null)
            {
                return;
            }
            if (!curNodeData.CanDrag)
            {
                e.Effect = DragDropEffects.None;
            }
        }

DragDrop 用來處理拖動結束時的邏輯

        private void TreeList_DragDrop(object sender, DragEventArgs e)
        {
            // 當前節點的父節點變化,則不允許拖動
            var dragNode = e.Data.GetData(typeof(TreeListNode)) as TreeListNode;
            var sourceParent = dragNode.ParentNode.GetValue(treeListColumn1) as PrjTableNode;

            var targetNode = treeList.CalcHitInfo(treeList.PointToClient(MousePosition)).Node;
            if (targetNode == null)
            {
                return;
            }
            PrjTableNode targetNodeParent = null;
            if (targetNode.ParentNode != null)
            {
                targetNodeParent = targetNode.ParentNode.GetValue(treeListColumn1) as PrjTableNode;
            }
            // 發生跨級移動
            if (sourceParent.Id != targetNodeParent.Id)
            {
                e.Effect = DragDropEffects.None;
                return;
            }
            // 移到子集
            if (AjustDirection(sender, e) == DragInsertPosition.AsChild)
            {
                e.Effect = DragDropEffects.None;
                return;
            }
        }
        /// <summary>
        /// 移動過程中的方向
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        private DragInsertPosition AjustDirection(object sender, DragEventArgs e)
        {
            var tl = sender as TreeList;
            //var dragNode = e.Data.GetData(typeof(TreeListNode)) as TreeListNode;
            //var hit = tl.CalcHitInfo(tl.PointToClient(new Point(e.X, e.Y)));
            var pi = typeof(TreeList).GetProperty("Handler", BindingFlags.Instance | BindingFlags.NonPublic);
            var handler = (TreeListHandler)pi.GetValue(tl, null);
            return handler.StateData.DragInfo.DragInsertPosition;

        }

AfterDragNode 用來處理拖動結束後的邏輯

        private void TreeList_AfterDragNode(object sender, AfterDragNodeEventArgs e)
        {
            // TODO:...

        }

3.總結

treeList是一個很強大的控制項,用來處理樹狀結構。本次需求中,處理節點拖拽話費了較長時間,也網上找了很多博文,但是都沒有直接解決我的問題,因此在這裡做個筆記。

後記:紙上得來終覺淺,絕知此事要躬行

本文來自博客園,作者:宣君{https://www.nhit.icu/},轉載請註明原文鏈接:https://www.cnblogs.com/ycit/p/17604994.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ## 目錄 - [Feign 和OpenFeign](#Feign-和OpenFeign) - [Feign](#Feign) - [OpenFeign](#OpenFeign) - [openFeign的優勢](#openFeign的優勢) - [OpenFeign應用](#OpenFeign應用 ...
  • 作為一名開發者,有很多場景需要用到內網穿透,比如:我們在接入一些大平臺做第三方應用時,在本地開發微信公眾號工具的時候需要讓微信平臺能否訪問到本地提供的介面。除此之外,還有很多其他場景,也會用到,比如:把放在家裡的NAS或伺服器暴露到公網上,這樣在外面的時候也可以隨時隨地的訪問。 說到內網傳統,TJ君 ...
  • #### win10 環境搭建 ##### 1.簡易安裝參考菜鳥教程,鏈接: ##### 2.詳細安裝 1. ##### Apache 伺服器安裝:Apache 是C語言實現的,專門用來提供HTTP服務;特性:簡單、速度快、性能穩定、可配置(代理) 2.1.1、主要用於解析靜態文本,併發性能高,側重 ...
  • ### application.yml文件中開啟mybatis自動駝峰映射 ```java configuration: #是否開啟自動駝峰命名規則映射:從資料庫列名到Java屬性駝峰命名的類似映射 map-underscore-to-camel-case: true ``` - 如果不開啟映射 在 ...
  • 本文探討了三種常見的加密演算法:MD5、DES和RAS的工作原理與特點。首先,MD5是一種不可逆的加密演算法,它將任意長度的數據轉化為固定長度的摘要,用於數據完整性校驗。然而,由於其存在碰撞攻擊的漏洞,MD5已經不再被推薦作為安全加密演算法。其次,DES是一種對稱可逆的加密演算法,它使用相同的密鑰進行加密和... ...
  • 本文將介紹ASP.NET Core SignalR,這是一個強大的實時通信庫,用於構建實時、雙向通信應用程式。我們將探討SignalR的基本概念、架構和工作原理,並提供一些示例代碼來幫助讀者更好地理解和使用SignalR。ASP.NET Core SignalR提供了一種簡單而強大的方式來構建實時通 ...
  • # Unity IPreprocessShaders Unity IPreprocessShaders是Unity引擎中的一個非常有用的功能,它可以讓開發者在編譯Shader時自定義哪些操作需要被執行。這個可以幫助開發者更好地控制Shader的編譯過程,確保在編譯Shader時執行必要的操作。在本文 ...
  • ## 引言 今天同事問了我一個問題,`System.Windows.Forms.Timer`是前臺線程還是後臺線程,我當時想的是它是跟著UI線程一起結束的,應該是前臺線程吧? 我確實沒有仔細研究過他們的異同,所以帶著這個疑問探究一下`System.Windows.Forms.Timer`。 ## S ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...