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

윈도우 폼 개발후 배포시 사이즈가 이상하다…?

AutoScaleMode열거형 Windows Forms에서 지원하는 여러 종류의 자동 크기 조정 모드를 지정합니다. 네임스페이스: System.Windows.Forms 어셈블리: System.Windows.Forms(System.Windows.Forms.dll) 구문 public enum AutoScaleMode 멤버 이름 설명 None 자동 크기조정을 사용할 수 없습니다. Font 클래스에서 사용하는글꼴(대개 시스템 글꼴)의 크기를 기준으로 크기를 제어합니다. Dpi...

read more
asp.net development server port issue

asp.net development server port issue

지금껏 C/S 만 위주로 개발을 하다 오랜만에 Web 관련 프로젝트를 하고있다.. 물론 Silverlight 라서 크게 문제되지는 않지만 8, 9 년 전에 PHP 하던게 Web 관련 일은 전부인지라... 이것 저것 걸리는게 많다... 그 와중에 간간히.. 때때로 매번.... Silverlight 쪽 소스 변경한 것을 확인할려고 솔루션 탐색기의 Web Project 를 디버그 모드로 실행하면("마우스 우클릭=>디버그=>새 인스턴스 시작") 위와 같은 에러가 난다......

read more

c# thread safe extension method

public static class ExtensionMethod { public static TResult SafeInvoke(this T isi, Func call) where T : ISynchronizeInvoke { if(isi.InvokeRequired) { IAsyncResult result = isi.BeginInvoke(call, new object[] { isi }); object endResult = isi.EndInvoke(result); return...

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