Joorr

devexpress grid의 column 들을 merge 하는 방법.


form1.cs


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

namespace WindowsApplication1
{
    public partial class Form1 : Form
    {
        private MyCellMergeHelper _Helper;
            
        private DataTable CreateTable(int RowCount)
        {
            DataTable tbl = new DataTable();
            tbl.Columns.Add("Name1", typeof(string));
            tbl.Columns.Add("Name2", typeof(string));
            tbl.Columns.Add("Name3", typeof(string));
            tbl.Columns.Add("Name4", typeof(string));
            for (int i = 0; i < RowCount; i++)
                tbl.Rows.Add(new object[] { String.Format("Name{0}", i), String.Format("Name{0}", i), String.Format("Name{0}", i), String.Format("Name{0}", i) });
            return tbl;
        }
        

        public Form1()
        {
            InitializeComponent();
            gridControl1.DataSource = CreateTable(20);
            _Helper =  new MyCellMergeHelper(gridView1);
            _Helper.AddMergedCell(1, 1, 2, "MyMergedCell1 (Very long text)");
            _Helper.AddMergedCell(2, 2, 3, "MyMergedCell2");
        }

        private void simpleButton1_Click(object sender, EventArgs e)
        {
            DevExpress.XtraGrid.Views.Base.GridCell[] cells = gridView1.GetSelectedCells();
            if (cells.Length == 2)
            {
                int rowHandle = cells[0].RowHandle;
                if (rowHandle == cells[1].RowHandle)
                {
                    object value = gridView1.GetRowCellValue(rowHandle, cells[0].Column);
                    _Helper.AddMergedCell(rowHandle, cells[0].Column.AbsoluteIndex, cells[1].Column.AbsoluteIndex, value);
                    gridView1.RefreshRow(rowHandle);
                }
            }
        }
    }    
}


MyCellMergeHelper class


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid.Drawing;
using DevExpress.XtraGrid.Columns;

namespace WindowsApplication1
{
    public class MyCellMergeHelper
    {
        private List<MyMergedCell> _MergedCells = new List<MyMergedCell>();
        public List<MyMergedCell> MergedCells
        {
            get { return _MergedCells; }
        }

        MyGridPainter painter;


        GridView _view;

        public MyCellMergeHelper(GridView view)
        {
            _view = view;
            view.CustomDrawCell += new RowCellCustomDrawEventHandler(view_CustomDrawCell);
            view.GridControl.Paint += new PaintEventHandler(GridControl_Paint);
            view.CellValueChanged += new CellValueChangedEventHandler(view_CellValueChanged);
            painter = new MyGridPainter(view);
        }

        public MyMergedCell AddMergedCell(int rowHandle, GridColumn col1, GridColumn col2)
        {
            MyMergedCell cell = new MyMergedCell(rowHandle, col1, col2);
            _MergedCells.Add(cell);
            return cell;
        }
        public void AddMergedCell(int rowHandle, int col1, int col2, object value)
        {
            AddMergedCell(rowHandle, _view.Columns[col1], _view.Columns[col2]);
        }

        public void AddMergedCell(int rowHandle, GridColumn col1, GridColumn col2, object value)
        {
            MyMergedCell cell = AddMergedCell(rowHandle, col1, col2);
            SafeSetMergedCellValue(cell, value);
        }



        public void SafeSetMergedCellValue(MyMergedCell cell, object value)
        {
            if (cell != null)
            {
                SafeSetCellValue(cell.RowHandle, cell.Column1, value);
                SafeSetCellValue(cell.RowHandle, cell.Column2, value);
            }
        }

        public void SafeSetCellValue(int rowHandle, GridColumn column, object value)
        {
            if (_view.GetRowCellValue(rowHandle, column) != value)
                _view.SetRowCellValue(rowHandle, column, value);
        }


        private MyMergedCell GetMergedCell(int rowHandle, GridColumn column)
        {
            foreach (MyMergedCell cell in _MergedCells)
            {
                if (cell.RowHandle == rowHandle && (column == cell.Column1 || column == cell.Column2))
                    return cell;
            }
            return null;
        }

        private bool IsMergedCell(int rowHandle, GridColumn column)
        {
            return GetMergedCell(rowHandle, column) != null;
        }

        private void DrawMergedCells(PaintEventArgs e)
        {
            foreach (MyMergedCell cell in _MergedCells)
            {
                painter.DrawMergedCell(cell, e);
            }
        }


        void view_CellValueChanged(object sender, CellValueChangedEventArgs e)
        {
            SafeSetMergedCellValue(GetMergedCell(e.RowHandle, e.Column), e.Value);  
        }

        void GridControl_Paint(object sender, PaintEventArgs e)
        {
            DrawMergedCells(e);
        }

        void view_CustomDrawCell(object sender, RowCellCustomDrawEventArgs e)
        {
            if (IsMergedCell(e.RowHandle, e.Column))
                e.Handled = !painter.IsCustomPainting;
        }
     
    }
}

MyGridPainter class


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid.Drawing;
using DevExpress.Utils.Drawing;
using DevExpress.XtraGrid.Drawing;
using DevExpress.Utils;
using DevExpress.XtraEditors.ViewInfo;

namespace WindowsApplication1
{
    public class MyGridPainter : GridPainter
    {


        public MyGridPainter(GridView view)
            : base(view)
        {

        }

        private bool _IsCustomPainting;
        public bool IsCustomPainting
        {
            get { return _IsCustomPainting; }
            set { _IsCustomPainting = value; }
        }

        public void DrawMergedCell(MyMergedCell cell, PaintEventArgs e)
        {
            int delta = cell.Column1.VisibleIndex - cell.Column2.VisibleIndex;
            if (Math.Abs(delta)>1)
                return;
            GridViewInfo vi = View.GetViewInfo() as GridViewInfo;
            GridCellInfo gridCellInfo1 = vi.GetGridCellInfo(cell.RowHandle, cell.Column1);
            GridCellInfo gridCellInfo2 = vi.GetGridCellInfo(cell.RowHandle, cell.Column2);
            if (gridCellInfo1 == null || gridCellInfo2 == null)
                return;
            Rectangle targetRect = Rectangle.Union(gridCellInfo1.Bounds, gridCellInfo2.Bounds);
            gridCellInfo1.Bounds = targetRect;
            gridCellInfo1.CellValueRect = targetRect;
            gridCellInfo2.Bounds = targetRect;
            gridCellInfo2.CellValueRect = targetRect;
            if (delta < 0)
                gridCellInfo1 = gridCellInfo2;
            Rectangle bounds = gridCellInfo1.ViewInfo.Bounds;
            bounds.Width = targetRect.Width;
            bounds.Height = targetRect.Height;
            gridCellInfo1.ViewInfo.Bounds = bounds;
            gridCellInfo1.ViewInfo.CalcViewInfo(e.Graphics);
            IsCustomPainting = true;
            GraphicsCache cache = new GraphicsCache(e.Graphics);
            gridCellInfo1.Appearance.FillRectangle(cache, gridCellInfo1.Bounds);
            DrawRowCell(new GridViewDrawArgs(cache, vi, vi.ViewRects.Bounds), gridCellInfo1);
            IsCustomPainting = false; ;
        }
    }    
}


MyMergedCell class


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Columns;

namespace WindowsApplication1
{
    public class MyMergedCell
    {

        public MyMergedCell(int rowHandle, GridColumn col1, GridColumn col2)
        {
            _RowHandle = rowHandle;
            _Column1 = col1;
            _Column2 = col2;
        }

        private GridColumn _Column2;
        private GridColumn _Column1;
        private int _RowHandle;
        public int RowHandle
        {
            get { return _RowHandle; }
            set { _RowHandle = value; }
        }

        public GridColumn Column1
        {
            get { return _Column1; }
            set
            {
                _Column1 = value;

            }
        }

        public GridColumn Column2
        {
            get { return _Column2; }
            set
            {
                _Column2 = value;

            }
        }
    }
}


원본 : https://www.devexpress.com/Support/Center/Example/Details/E2472