使用DevExpress的GridControl實現多層級或無窮級的嵌套列表展示


在我早期的隨筆《在GridControl表格控件中實現多層級主從表數據的展示》中介紹過GridControl實現二級、三級的層級列表展示,主要的邏輯就是構建GridLevelNode並添加到LevelTree集合里面,手動創建多個承載顯示的gridview,然后添加到視圖集合里面去吧,不過這個是已知層級的情況下,如果是無窮級,這種手工創建視圖的方式,肯定不太適合,而且很繁瑣,我們本篇隨筆來改進一下,介紹如何實現多層級或無窮級的嵌套列表展示。

1、回顧二級、三級層級的處理

根據數據展示的定義,我們構建一些測試的數據,如下所示。

    //創建測試數據
    var result = new Detail2Result()
    {
        Name = "測試",
        Description = "描述內容",
        Detail2List = new List<DetailInfo>()
        {
            new DetailInfo()
            {
                Name = "111測試",
                Description = "111描述內容"
            },
            new DetailInfo()
            {
                Name = "222測試",
                Description = "222描述內容"
            },
            new DetailInfo()
            {
                Name = "333測試",
                Description = "333描述內容"
            }
        }
    };

    //構造一個記錄的集合
    var list = new List<Detail2Result>() { result };

接着通過代碼創建我們需要的視圖信息,如創建主表的GridView顯示如下所示。

GridView grv2 = null;
/// <summary>
/// 創建第二個視圖
/// </summary>
private void CreateLevelView()
{
    var grv = this.gridView1;
    var gridControl = this.gridControl1;

    //創建一個從表的GridView對象
    grv2 = new GridView();
    grv2.ViewCaption = "記錄明細";
    grv2.Name = "grv2";
    grv2.GridControl = gridControl;

    //構建GridLevelNode並添加到LevelTree集合里面
    var node = new GridLevelNode();
    node.LevelTemplate = grv2;
    node.RelationName = "Detail2List";//這里對應集合的屬性名稱
    gridControl.LevelTree.Nodes.AddRange(new GridLevelNode[]
    {
        node
    });

    //添加對應的視圖集合顯示
    gridControl.ViewCollection.Clear();
    gridControl.ViewCollection.AddRange(new BaseView[] { grv, grv2 });

    //創建從表顯示的列
    grv2.Columns.Clear();
    grv2.CreateColumn("ID", "ID");
    grv2.CreateColumn("Name", "名稱");
    grv2.CreateColumn("Description", "描述內容");

    //設置非只讀、可編輯
    grv2.OptionsBehavior.ReadOnly = false;
    grv2.OptionsBehavior.Editable = true;
}

剩下的就是數據的綁定處理了,這里構建列表,綁定數據源展示即可

    //構造一個記錄的集合
    var list = new List<Detail2Result>() { result };
    //綁定數據源
    this.gridControl1.DataSource = list;

可以看到例子的效果界面如下所示。

二級和三級處理的方式類似,就不再贅述了。

  

2、多層級或無窮級的嵌套列表展示

如果是不確定的多層級列表展示,那么我們應該如何處理呢,手工逐一創建視圖的方式,肯定不合適,畢竟有時候數據層次是不確定的,如下數據結構所示,它是一個嵌套的數據結構。

    /// <summary>
    /// 本類用於演示多層級的數據列表的展示
    /// </summary>
    public class DetailNodeInfo
    {
        public DetailNodeInfo()
        {
            this.ID = Guid.NewGuid().ToString();
        }

        /// <summary>
        /// ID標識
        /// </summary>
        public string ID { get; set; }

        /// <summary>
        /// 名稱
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 描述信息
        /// </summary>
        public string Description { get; set; }

        public List<DetailNodeInfo> Children { get; set; } = new List<DetailNodeInfo>();//初始化

    }

這里面我們的嵌套列表使用了Children屬性。

這樣我們創建視圖的時候,只需要創建主視圖gridview即可,如下所示

        /// <summary>
        /// 創建第一個視圖
        /// </summary>
        private void CreateGridView()
        {
            var grv = this.gridView1;
            var gridControl = this.gridControl1;

            //創建從表顯示的列
            grv.Columns.Clear();
            grv.CreateColumn("ID", "ID");//.Visible = false;
            grv.CreateColumn("Name", "名稱");
            grv.CreateColumn("Description", "描述內容");

            //列表是否只讀
            grv.OptionsBehavior.ReadOnly = false;
            //列表是否可以編輯
            grv.OptionsBehavior.Editable = true;

            //gridview列表注冊的時候,觸發處理
            gridControl.ViewRegistered += GridControl_ViewRegistered;
        }

其中紅色的ViewRegistered是用來觸發從表視圖的時候,我們處理列頭的中文信息的

        private void GridControl_ViewRegistered(object sender, ViewOperationEventArgs e)
        {
            var detailView = e.View as GridView;
            if (detailView != null)
            {
                SetGridViewCaption(detailView);
            }
        }
        private void SetGridViewCaption(GridView view)
        {
            foreach (GridColumn column in view.Columns)
            {
                SetColumnCaption(column, "id", "編號");
                SetColumnCaption(column, "name", "名稱");
                SetColumnCaption(column, "name", "描述內容");
            }
        }

        private void SetColumnCaption(GridColumn column, string fieldName, string caption)
        {
            if(column != null && column.FieldName.Equals(fieldName, StringComparison.OrdinalIgnoreCase))
            {
                column.Caption = caption;
            }
        }

為了測試無窮級嵌套列表的展示,我們創建了一個多級的嵌套列表數據,如下所示。

        /// <summary>
        /// 綁定數據源
        /// </summary>
        private void BindData()
        {
            //創建測試數據
            var result = new DetailNodeInfo()
            {
                Name = "測試1",
                Description = "描述內容",
                //二級列表
                Children = new List<DetailNodeInfo>()
                {
                    new DetailNodeInfo()
                    {
                        Name = "測試2",
                        Description = "描述內容",
                             
                        //三級列表
                        Children = new List<DetailNodeInfo>()
                        {
                            new DetailNodeInfo()
                            {
                                Name = "3測試",
                                Description = "描述內容",

                                //四級列表
                                Children = new List<DetailNodeInfo>()
                                {
                                    new DetailNodeInfo()
                                    {
                                        Name = "4測試",
                                        Description = "描述內容",
                                        Children = new List<DetailNodeInfo>()
                                        {
                                            new DetailNodeInfo()
                                            {
                                                Name = "5測試",
                                                Description = "描述內容",
                                                Children = null
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            };

綁定操作代碼和之前處理沒有什么異樣。

  //構造一個記錄的集合
  var list = new List<DetailNodeInfo>() { result };
   //綁定數據源
    this.gridControl1.DataSource = list;

 

注意,以上列表只是展示,並沒有保存處理。

如果需要綁定可以直接錄入並保存的操作,列表必須為BindingList<T>類型,這個才能記錄狀態的,如下數據結構定義所示。

 

詳細可以參考我隨筆《基於主從表數據錄入的處理》 中的介紹。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM