여기에서 체크박스가 표시되는 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