여기에서 체크박스가 표시되는 Column 의 FieldName 은 “Select”로 함
1. RepositoryItemCheckEdit 를 전역변수로 선언
// CheckBox 로 표시될 ColumnEdit
RepositoryItemCheckEdit _repChkYN = new RepositoryItemCheckEdit();
// 전체선택 체크박스 상태
private bool _stateAllSel = false;
2. ColumnEdit 기본설정 및 체크박스를 표시할 컬럼에 ColumnEdit 를 지정
_repChkYN.ValueChecked = "Y";
_repChkYN.ValueUnchecked = "N"
_repChkYN.ValueGrayed = "";
colSel.ColumnEdit = _repChkYN;
3. ColumnEdit 및 GridVIew 에 다음 이벤트 추가
// 선택 CheckEdit 변경
_repChkYN.EditValueChanged += _repChkYN_EditValueChanged;
void _repChkYN_EditValueChanged(object sender, EventArgs e)
{
DataRow dr = gvMain.GetFocusedDataRow();
dr["Select"] = gvMain.EditingValue;
dr.EndEdit();
_stateAllSel = IsAllSelected();
gvMain.LayoutChanged();
}
// 선택컬럼이 모두 선택되어있는지 여부를 리턴
bool IsAllSelected()
{
if(GridData != null)
{
foreach(DataRow dr in GridData.Rows)
{
if(dr["Select"].GMSToString() == "N")
{
return false;
}
}
return true;
}
return false;
}
// 컬럼헤더 CustomDraw
this.gvMain.CustomDrawColumnHeader += gvMain_CustomDrawColumnHeader;
void gvMain_CustomDrawColumnHeader(object sender, ColumnHeaderCustomDrawEventArgs e)
{
if(e.Column != colSel)
{
return;
}
Rectangle rect = e.Bounds;
e.Appearance.FillRectangle(e.Cache, rect);
e.Info.Caption = "";
e.Painter.DrawObject(e.Info);
TextOptions to = e.Appearance.TextOptions;
to.HAlignment = HorzAlignment.Center;
int textHeight = Math.Round(DevExpress.Utils.Paint.XPaint.Graphics.CalcTextSize(e.Graphics, "선택", e.Appearance.Font, e.Appearance.GetStringFormat(to), colSel.Width).Height).CPJToInt();
DevExpress.Utils.Paint.XPaint.Graphics.DrawString(e.Cache, "선택", e.Appearance.Font, e.Appearance.GetTextureBrush()
, new Rectangle(e.Bounds.X, (e.Bounds.Height / 2) - textHeight, e.Bounds.Width, textHeight), e.Appearance.GetStringFormat(to));
Size size = CheckBoxRenderer.GetGlyphSize(e.Graphics, CheckBoxState.UncheckedNormal);
Rectangle rectCheck = new Rectangle((rect.Width - size.Width) / 2, (rect.Height - size.Height) / 2 + textHeight, size.Width, size.Height);
DrawCheckBox(e.Graphics, rectCheck);
e.Handled = true;
}
// 현재테마와 동일하게 체크박스를 그려줌
void DrawCheckBox(Graphics g, Rectangle r)
{
DevExpress.XtraEditors.ViewInfo.CheckEditViewInfo info = default(DevExpress.XtraEditors.ViewInfo.CheckEditViewInfo);
DevExpress.XtraEditors.Drawing.CheckEditPainter painter = default(DevExpress.XtraEditors.Drawing.CheckEditPainter);
DevExpress.XtraEditors.Drawing.ControlGraphicsInfoArgs args = default(DevExpress.XtraEditors.Drawing.ControlGraphicsInfoArgs);
info = (CheckEditViewInfo)_repChkYN.CreateViewInfo();
painter = (CheckEditPainter)_repChkYN.CreatePainter();
info.EditValue = _stateAllSel ? "Y" : "N";
info.Bounds = r;
info.CalcViewInfo(g);
args = new DevExpress.XtraEditors.Drawing.ControlGraphicsInfoArgs(info, new DevExpress.Utils.Drawing.GraphicsCache(g), r);
painter.Draw(args);
args.Cache.Dispose();
}
// Grid Click 이벤트
this.gvMain.MouseUp += gvMain_MouseUp;
private void gvMain_MouseUp(object sender, MouseEventArgs e)
{
if(e.Button == MouseButtons.Left && e.Clicks == 1)
{
GridView view = (GridView)sender;
GridHitInfo hInfo = view.CalcHitInfo(e.Location);
if(hInfo.HitTest == GridHitTest.Column && hInfo.Column == colSel)
{
_stateAllSel = !_stateAllSel;
for(int k = 0 ; k < gvMain.DataRowCount ; k++)
{
gvMain.SetRowCellValue(k, "Select", _stateAllSel ? "Y" : "N");
}
}
}
}
============ 스크린샷 ============

============ 요약 ============
- Row 의 Data 는 “Y”, “N” 으로 true, false 를 구분함.
- 컬럼헤더의 CheckBox 는 Custom Draw 하되 Caption 다음에 한줄 띄워서 CheckBox 를 표시하고, 중앙정렬
- 컬럼헤더의 CheckBox 를 클릭하는 경우 모든행의 체크상태가 한번에 변경이 되고,
데이터 행의 체크값을 변경시 컬럼헤더의 체크상태는 모든행의 데이터가 체크표시된 경우만 체크되게 동작함.
그래서 데이터행의 체크상태가 변경되는 시점에 컬럼헤더의 체크박스도 다시 그려줘야함…
==== 고민한 부분 ====
데이터행의 체크상태가 변경되는 시점에 컬럼헤더의 체크박스도 다시 그려줘야함…
위 부분에서 행이 바뀌지 않는한 DataSource 변경이벤트(ValueChanged) 가 발생되지 않아서, 행을 변경해야 컬럼헤더의 체크상태가 반영이됨.
// 이 문제를 해결하기 위해 RepositoryItemCheckEdit 의 EditValueChanged 이벤트에서 DataSource 의 값을 바로 변경시켜주고,
DataRow dr = gvMain.GetFocusedDataRow();
dr["Select"] = gvMain.EditingValue;
dr.EndEdit();
// 전체선택여부 전역변수를 갱신한 다음
_stateAllSel = IsAllSelected();
// LayoutChanged 호출해줘야 GridView 의 CustomDrawColumnHeader 이벤트가 발생이 되면서 컬럼헤더의 체크상태가 업데이트됨.
// (gvMain.LayoutChanged(); 를 호출하지 않고, Grid 의 ValueChanged 이벤트만 호출해봐야 실제 UI 에 반영이 안됨. gvMain.LayoutChanged(); 를 찾는데 애먹었음)
gvMain.LayoutChanged();
0 Comments