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

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

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

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

read more
Blazor bootstrap theme sample

Blazor bootstrap theme sample

전체 소스 코드는 다음 Github 의 BlazorBootswatchTheme 폴더에 있습니다 https://github.com/kkomzi7179/BlazorWASMSample .net 으로 생성된 blazor wasm 기본 템플릿은 bootstrap 을 기반으로 하고 있습니다. 그리고 bootstratp 을 기반으로 다양한 테마를 제공하는 bootswatch 오픈소스 프로젝트가 있습니다. https://github.com/thomaspark/bootswatch MIT...

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.

무료 온라인 전광판

전광판

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

Carousel

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

Pin It on Pinterest

Shares
Share This

Share This

Share this post with your friends!

Shares