いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

DevExpress奮闘記-084 (XtraTreeListのUnboundModeと動的ローディング)(TreeList, BeforeExpand, Dynamic Loading, KeyFieldName, ParentFieldName)


TreeListの動的ローディングとUnbound Modeのやり方を
良く忘れるので、自分用にメモメモ。


リファレンスは以下の部分が参考になります。


データバウンドモードで利用する場合は

  • KeyFieldName
  • ParentFieldName

がとても大事。


逆にアンバウンドモードで利用する場合は
上記のプロパティを設定する必要は無い。


ノードを展開したタイミングで動的にノードを追加するには

  • BeforeExpandイベント

をハンドルします。


以下、サンプルです。
以下のサンプルでは、Loadイベント時のデータソースを
変更することで、バウンドモードとアンバウンドモードの
動きを見れるようなっています。

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using DevExpress.XtraEditors;
using DevExpress.XtraTreeList;
using DevExpress.XtraTreeList.Nodes;

namespace XtraTreeList_DynamicLoading_UnboundMode
{
    public partial class Form1 : XtraForm
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //SetBoundDataSource();
            SetUnboundDataSource();

            lstEvents.Items.Clear();
        }

        void trlMain_FocusedNodeChanged(object sender, FocusedNodeChangedEventArgs e)
        {
            TreeListNode node = e.Node;

            lstEvents.Items.Add(
                string.Format(
                    "NODE: [ID]={0}, [Text]={1}, [Level]={2}, [Self Id]={3}",
                    node.Id,
                    node.GetValue("Name"),
                    node.Level,
                    node.GetValue("Id")
                )
            );
        }

        void trlMain_BeforeExpand(object sender, BeforeExpandEventArgs e)
        {
            if (e.Node == null)
            {
                return;
            }

            if (e.Node.Nodes.Count != 0)
            {
                return;
            }

            TreeList tree = sender   as TreeList;
            Random   rnd  = tree.Tag as Random;

            trlMain.BeginUnboundLoad();

            int count = rnd.Next(1000);
            for (int i = 0; i < count; i++)
            {
                int id = (e.Node.Id * 5 + (i + 1));

                TreeListNode newNode = trlMain.AppendNode(new object[] { id, string.Format("SubNode-{0}", id) }, e.Node);
                newNode.HasChildren = true;
            }

            trlMain.EndUnboundLoad();
        }

        private void SetUnboundDataSource()
        {
            trlMain.BeginUpdate();

            trlMain.Columns.Add();
            trlMain.Columns[0].Caption      = "Id";
            trlMain.Columns[0].VisibleIndex = 0;
            trlMain.Columns[0].Visible      = false;

            trlMain.Columns.Add();
            trlMain.Columns[1].Caption      = "Name";
            trlMain.Columns[1].VisibleIndex = 1;

            trlMain.EndUpdate();
            trlMain.BeginUnboundLoad();

            for (int i = 0; i < 1000; i++)
            {
                TreeListNode newRootNode = trlMain.AppendNode(new object[] { i, string.Format("RootNode-{0}", i) }, null);
                newRootNode.HasChildren = true;
            }

            trlMain.EndUnboundLoad();

            trlMain.FocusedNodeChanged += trlMain_FocusedNodeChanged;
            trlMain.BeforeExpand       += trlMain_BeforeExpand;

            trlMain.OptionsView.ShowHorzLines = false;
            trlMain.OptionsView.ShowVertLines = false;

            trlMain.Tag = new Random();
        }

        private void SetBoundDataSource()
        {
            DataTable table = new DataTable();

            table.Columns.Add("Id",       typeof(int));
            table.Columns.Add("Name",     typeof(string));
            table.Columns.Add("ParentId", typeof(int));

            for (int i = 0; i < 100; i++)
            {
                table.LoadDataRow(new object[] { i, string.Format("Node-{0}", i), DBNull.Value }, true);
            }

            Random rnd = new Random();
            foreach (DataRow row in table.Rows)
            {
                row.SetField<int>("ParentId", rnd.Next(table.Rows.Count));
            }

            table.AcceptChanges();

            trlMain.KeyFieldName    = "Id";
            trlMain.ParentFieldName = "ParentId";

            trlMain.DataSource = table;
            trlMain.CollapseAll();

            trlMain.FocusedNodeChanged += trlMain_FocusedNodeChanged;

            trlMain.OptionsView.ShowHorzLines = false;
            trlMain.OptionsView.ShowVertLines = false;
        }        
    }
}

実行すると以下のような感じ。
ノードを展開するタイミングで、BeforeExpandイベントが発生するので
子のノードを追加しています。


サンプルは以下の場所にアップしてあります。

================================
過去の記事については、以下のページからご参照下さい。