いろいろ備忘録日記

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

DevExpress奮闘記-038 (Detail側の件数が0件の場合にプラスボタンを非表示にする)(GridControl, CustomDrawCell, CellButtonRect, CellValueRect, Rectangle.Empty)


DevExpressのKBに面白いのがあったので、メモ代わりにここに記述します。


参考にしているKBは以下です。


GridControlでは、Master-Detail表示が出来ますが、その際Detail側のデータが
0件の場合、展開するためのボタン(+ボタン)が押せないような状態で表示されます。


これはこれでいいのですが、Detail側が0件の場合はボタンそのものも表示したくない
場合には、以下のイベントをハンドルします。

GridView.CustomDrawCellイベント


このイベントのイベント引数に、Cellプロパティがあり
それをGridCellInfoクラスにキャストすることで、展開ボタンの
描画を操作できるようになります。以下のプロパティを設定します。

GridCellInfo.CellButtonRectプロパティ


このプロパティに空のRectangleを設定すればOKです。


以下、サンプルです。

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;

namespace GridControlCustomDrawNodeSample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            InitializeEvents();
        }

        private void InitializeEvents()
        {
            Load += (s, e) =>
                {
                    grdMain.DataSource = CreateSampleData();
                };

            grvMain.CustomDrawCell += (s, e) =>
                {
                    GridView view = s as GridView;

                    //
                    // 開閉ボタンが表示されるのは、常にVisibleIndexが0の列となる。
                    // (AbsoluteIndexを利用すると表示時の列の位置が違っている可能性があるため)
                    //
                    // 後は、IsMasterRowEmptyを利用してDetail側のデータが存在するか否かを判別する.
                    //
                    if (e.Column.VisibleIndex == 0 && view.IsMasterRowEmpty(e.RowHandle))
                    {
                        if (!chkToggleCustomDrawCell.Checked)
                        {
                            return;
                        }

                        //
                        // ボタン領域に空のRectangleを描画.
                        //
                        // ボタン領域はCellButtonRectで参照できる。
                        // 尚、値が表示される領域はCellValueRectで参照できる。
                        //
                        GridCellInfo cell = (e.Cell as GridCellInfo);
                        cell.CellButtonRect = Rectangle.Empty;
                    }
                };

            chkToggleCustomDrawCell.CheckedChanged += (s, e) =>
                {
                    grdMain.DataSource = null;
                    grdMain.DataSource = CreateSampleData();
                };
        }

        private List<Parent> CreateSampleData()
        {
            //
            // サンプルデータを構築.
            //
            Parent p1 = new Parent
            {
                Id = 1,
                Name = "Parent1",
                Childs = new List<Child> { new Child { ChildId = 1, ChildName = "Child1" } }
            };

            Parent p2 = new Parent
            {
                Id = 2,
                Name = "Parent2",
                Childs = new List<Child>()
            };

            Parent p3 = new Parent
            {
                Id = 3,
                Name = "Parent3",
                Childs = new List<Child> { new Child { ChildId = 2, ChildName = "Child2" }, new Child { ChildId = 3, ChildName = "Child3" } }
            };

            return new List<Parent>{ p1, p2, p3 };
        }
    }

    public class Parent
    {
        public int Id
        {
            get;
            set;
        }

        public string Name
        {
            get;
            set;
        }

        public List<Child> Childs
        {
            get;
            set;
        }
        
    }

    public class Child
    {
        public int ChildId
        {
            get;
            set;
        }

        public string ChildName
        {
            get;
            set;
        }
    }
}


実行すると以下のようになります。

[通常の状態]
MasterDetail1.png 直


[ボタンのエリアを描画しない版]
MasterDetail2.png 直


追記)今見ると、フォームのキャプションがCustomDrawNodeのサンプルになってる・・・(恥