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

Published Nov 19, 2012 | Updated Sep 28, 2022 | 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

C# 으로 사용자 입력을 받아 동작하는 콘솔 프로그램 구현

C# 으로 사용자 입력을 받아 동작하는 콘솔 프로그램 구현

네이버 지식인에서 우연히 보게 된 누군가의 질문... c# 콘솔 형태의 프로그램이며, 일정 갯수의 숫자를 데이터로 입력 받아 최대값/최소값 등을 구하거나 종료할 수 있는 기능을 하는 프로그램이 요구사항 이었다 내가 답변한 원문은 여기 : C# 프로그래밍 질문 : 지식iN (naver.com)네이버 지식인 링크 실제 프로그램이 실행되는 스크린샷은 다음 이미지와 같습니다. 프로그램이 실행되면 메뉴 설명을 출력합니다. 메뉴 선택에서 0~3 까지 숫자를 입력 받아 메뉴 선택의 용도로...

read more

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.

Banner IT Service

전광판

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

Carousel

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

Pin It on Pinterest

Shares
Share This

Share This

Share this post with your friends!

Shares