DevExpress XtraGrid 의 RepositoryItemCheckEdit 컬럼의 헤더에 전체선택(해제)기능 넣기

Published Nov 19, 2012 | Updated Feb 24, 2023 | 0 comments

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

Learn more on this topic

Related Blog Posts

Join in the conversation

Leave a Comment

0 Comments

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

무료 온라인 전광판

전광판

텍스트를 입력하고 텍스트 효과 및 배경효과 를 변경해서 전체화면으로 표시할 수 있는 전광판 용도로 사용하실 수 있습니다. 각종 스포츠 및 공연 관람시 응원 용도로 사용이 가능합니다.

Carousel

여러개의 슬라이드를 추가하여 프레젠테이션 및 이미지 슬라이드 용도로 사용하실 수 있습니다. 브라우저가 포함된 IT 기기로 큰 모니터에 연결하여 매장 내 공지사항 및 메뉴소개를 이미지로 표시할 수 있습니다.

Pin It on Pinterest

Shares
Share This

Share This

Share this post with your friends!

Shares