devexpress | How to merge cells horizontally in GridView
develop/c#2017. 3. 14. 11:19
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