#region using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Drawing; using System.Windows.Forms; using CSFrameworkV5.Library.CommonForms; using DevExpress.Data; using DevExpress.Utils; using DevExpress.Utils.Drawing; using DevExpress.Utils.Menu; using DevExpress.XtraEditors.Drawing; using DevExpress.XtraEditors.Repository; using DevExpress.XtraEditors.ViewInfo; using DevExpress.XtraGrid.Columns; using DevExpress.XtraGrid.Menu; using DevExpress.XtraGrid.Views.Base; using DevExpress.XtraGrid.Views.Grid; using DevExpress.XtraGrid.Views.Grid.ViewInfo; #endregion namespace CSFrameworkV5.Library.CommonClass { /// /// C# GridView列头添加CheckBox控件实现全选功能 /// by C/S框架网 www.csframework.com /// public class ColumnHeaderCheckBox { private GridColumn _CheckColumn; //自动创建的Column private RepositoryItemCheckEdit _CheckEdit; private ArrayList _CheckedRows; protected GridView _GridView; protected ArrayList _Selection; public ColumnHeaderCheckBox() { _Selection = new ArrayList(); _CheckedRows = new ArrayList(); } public ColumnHeaderCheckBox(GridView view, GridColumn checkColumn, bool showMenu = true) : this() { _CheckColumn = checkColumn; _CheckColumn.OptionsColumn.Printable = DefaultBoolean.False; View = view; if (showMenu) { view.PopupMenuShowing -= OnShowGridMenu; view.PopupMenuShowing += OnShowGridMenu; } } public GridColumn CheckMarkColumn => _CheckColumn; /// /// 勾选的记录数 /// private int SelectedCount => _CheckedRows.Count; /// /// 返回过滤后的实际记录数 /// public int SelectedCountReal { get { var dt = SelectedTable; return dt == null ? 0 : dt.Rows.Count; } } /// /// 返回过滤后勾选的表 /// public DataTable SelectedTable { //ok get { if (_GridView.GridControl.DataSource != null) { var dt = (_GridView.GridControl.DataSource as DataTable) .Clone(); foreach (DataRowView rv in _CheckedRows) dt.Rows.Add(rv.Row.ItemArray); dt.AcceptChanges(); return GetFilterTable(dt); } return null; } } /// /// 勾选的记录 /// private ArrayList Selection => _CheckedRows; public GridView View { get => _GridView; set { //设置不同的表格对象 if (!ReferenceEquals(_GridView, value)) { Detach(); //取消上一个GridView的事件 Attach(value); } _GridView = value; } } private void _GridView_ColumnFilterChanged(object sender, EventArgs e) { //this.ClearSelection(); } private void _GridView_StartSorting(object sender, EventArgs e) { //this.ClearSelection(); } protected virtual void Attach(GridView view) { if (view == null) return; _GridView = view; _Selection.Clear(); _CheckedRows.Clear(); _CheckEdit = (RepositoryItemCheckEdit)view.GridControl.RepositoryItems.Add( "CheckEdit"); _CheckEdit.EditValueChanged += Edit_EditValueChanged; _CheckColumn.OptionsColumn.AllowSort = DefaultBoolean.False; _CheckColumn.FieldName = "CheckMarkSelection"; _CheckColumn.Caption = "Mark"; _CheckColumn.OptionsColumn.ShowCaption = false; _CheckColumn.UnboundType = UnboundColumnType.Boolean; _CheckColumn.ColumnEdit = _CheckEdit; view.Click += View_Click; view.CustomDrawColumnHeader += View_CustomDrawColumnHeader; view.CustomDrawGroupRow += View_CustomDrawGroupRow; view.CustomUnboundColumnData += view_CustomUnboundColumnData; _GridView.ColumnFilterChanged += _GridView_ColumnFilterChanged; _GridView.StartSorting += _GridView_StartSorting; } public void ClearSelection() { _Selection.Clear(); _CheckedRows.Clear(); Invalidate(); } private string ConvertActiveFilterString(string ActiveFilterString) { while (ActiveFilterString.IndexOf(".") >= 0) { var i = ActiveFilterString.IndexOf("."); var im = ActiveFilterString.IndexOf("m", i, 4); if (Equals(im - i, 3)) ActiveFilterString = ActiveFilterString.Remove(im, 1); ActiveFilterString = ActiveFilterString.Remove(i, 1); ActiveFilterString = ActiveFilterString.Insert(i, "~"); } return ActiveFilterString.Replace("~", "."); } /// /// 创建菜单项DXMenuItem /// /// GridViewMenu /// 菜单标题 /// 菜单图片 /// Click 事件 /// public static void CreatePopupMenuItem(GridViewMenu owner, string caption, Image image, EventHandler clickEvent, bool beginGroup) { var item = new DXMenuItem(caption); item.Image = image; item.Click += clickEvent; item.Tag = owner.View; //保存GridView引用,在DXMenuItem事件内快速找到GridView item.BeginGroup = beginGroup; //item.Appearance.Name = _columnName; owner.Items.Add(item); } protected virtual void Detach() { if (_GridView != null) { _GridView.Click -= View_Click; _GridView.CustomDrawColumnHeader -= View_CustomDrawColumnHeader; _GridView.CustomDrawGroupRow -= View_CustomDrawGroupRow; _GridView.CustomUnboundColumnData -= view_CustomUnboundColumnData; } } protected void DrawCheckBox(Graphics g, Rectangle r, bool Checked, bool Grayed) { var info = default(CheckEditViewInfo); var painter = default(CheckEditPainter); var args = default(ControlGraphicsInfoArgs); info = (CheckEditViewInfo)_CheckEdit.CreateViewInfo(); painter = (CheckEditPainter)_CheckEdit.CreatePainter(); if (Grayed) info.EditValue = _CheckEdit.ValueGrayed; else info.EditValue = Checked; info.Bounds = r; info.CalcViewInfo(g); args = new ControlGraphicsInfoArgs(info, new GraphicsCache(g), r); painter.Draw(args); args.Cache.Dispose(); } private void Edit_EditValueChanged(object sender, EventArgs e) { View.PostEditor(); } /// /// 过滤表.GridView.ActiveFilterString /// /// 勾选的表 /// private DataTable GetFilterTable(DataTable checkedTable) { var filter = _GridView.ActiveFilterString; if (string.IsNullOrEmpty(filter)) return checkedTable; checkedTable.DefaultView.RowFilter = ConvertActiveFilterString(filter); return checkedTable.DefaultView.ToTable(); } private int GetSelectedRowHandle(object row) { var i = _Selection.IndexOf(row); return i; } private int GroupRowSelectionStatus(int rowHandle) { var count = 0; var i = 0; for (i = 0; i <= View.GetChildRowCount(rowHandle) - 1; i++) { var row = View.GetChildRowHandle(rowHandle, i); if (View.IsGroupRow(row)) { var g = GroupRowSelectionStatus(row); if (g < 0) return g; if (g > 0) count += 1; } else { if (IsRowSelected(row)) count += 1; } } if (count == 0) return 0; if (count == View.GetChildRowCount(rowHandle)) return 1; return -1; } private void Invalidate() { View.BeginUpdate(); View.EndUpdate(); View.Invalidate(); } private bool IsGroupRowSelected(int rowHandle) { var i = 0; for (i = 0; i <= View.GetChildRowCount(rowHandle) - 1; i++) { var row = View.GetChildRowHandle(rowHandle, i); if (View.IsGroupRow(row)) { if (!IsGroupRowSelected(row)) return false; } else { if (!IsRowSelected(row)) return false; } } return true; } public bool IsRowSelected(int sourceRowIndex) { //ok var h = View.GetRowHandle(sourceRowIndex); if (View.IsGroupRow(h)) return IsGroupRowSelected(h); var row = View.GetRow(h); return GetSelectedRowHandle(row) != -1; } private void OnClick_RemoveCheckedRows(object sender, EventArgs e) { if (Selection.Count == 0) return; //删除全部已勾选记录 var dt = _GridView.GridControl.DataSource as DataTable; foreach (DataRowView rv in Selection) if (dt.Rows.IndexOf(rv.Row) >= 0) dt.Rows.Remove(rv.Row); dt.AcceptChanges(); _CheckedRows.Clear(); _Selection.Clear(); } private void OnClick_RemoveRow(object sender, EventArgs e) { if (_GridView.FocusedRowHandle < 0) return; var R = _GridView.GetFocusedDataRow(); _CheckedRows.Remove(R); _Selection.Remove(R); //删除当前记录 var dt = _GridView.GridControl.DataSource as DataTable; dt.Rows.Remove(R); dt.AcceptChanges(); _GridView.GridControl.RefreshDataSource(); } private void OnClick_RemoveUncheckedRows(object sender, EventArgs e) { //删除全部未勾选记录 var dt = _GridView.GridControl.DataSource as DataTable; var list = new List(); for (var i = 0; i <= dt.Rows.Count - 1; i++) if (!IsRowSelected(i)) list.Add(dt.Rows[i]); foreach (var r in list) dt.Rows.Remove(r); dt.AcceptChanges(); } private void OnClick_ReverseCheck(object sender, EventArgs e) { //反选 var dt = _GridView.GridControl.DataSource as DataTable; for (var i = 0; i <= dt.Rows.Count - 1; i++) SelectRow(i, !IsRowSelected(i)); } private void OnShowGridMenu(object sender, PopupMenuShowingEventArgs e) { if (GridMenuType.Row == e.MenuType) { var res = new frmImageRes(); CreatePopupMenuItem(e.Menu, "隐藏当前记录", res.imgCheck.Images[0], OnClick_RemoveRow, true); CreatePopupMenuItem(e.Menu, "隐藏已勾选的记录", res.imgCheck.Images[1], OnClick_RemoveCheckedRows, false); CreatePopupMenuItem(e.Menu, "隐藏未勾选的记录", res.imgCheck.Images[2], OnClick_RemoveUncheckedRows, false); CreatePopupMenuItem(e.Menu, "反向勾选", res.imgCheck.Images[3], OnClick_ReverseCheck, false); } } public void SelectAll() { //ok _Selection.Clear(); _CheckedRows.Clear(); var i = 0; for (i = 0; i <= View.DataRowCount - 1; i++) { _Selection.Add(View.GetRow(i)); _CheckedRows.Add(View.GetRow(i)); } Invalidate(); } private void SelectGroup(int rowHandle, bool select) { if (IsGroupRowSelected(rowHandle) & select) return; var i = 0; for (i = 0; i <= View.GetChildRowCount(rowHandle) - 1; i++) { var childRowHandle = View.GetChildRowHandle(rowHandle, i); if (View.IsGroupRow(childRowHandle)) SelectGroup(childRowHandle, select); else SelectRow(childRowHandle, select, false); } Invalidate(); } public void SelectRow(int sourceRowIndex, bool select) { SelectRow(sourceRowIndex, select, true); } private void SelectRow(int sourceRowIndex, bool select, bool invalidate) { //ok if (IsRowSelected(sourceRowIndex) == select) return; var h = View.GetRowHandle(sourceRowIndex); var row = View.GetRow(h); if (select) { _Selection.Add(row); _CheckedRows.Add(row); } else { _Selection.Remove(row); _CheckedRows.Remove(row); } if (invalidate) Invalidate(); } private void View_Click(object sender, EventArgs e) { var info = default(GridHitInfo); var pt = View.GridControl.PointToClient(Control.MousePosition); info = View.CalcHitInfo(pt); if (info.InColumn & ReferenceEquals(info.Column, _CheckColumn)) { if (SelectedCount == View.DataRowCount) ClearSelection(); else SelectAll(); } if (info.InRow & View.IsGroupRow(info.RowHandle) & (info.HitTest != GridHitTest.RowGroupButton)) { var selected = IsGroupRowSelected(info.RowHandle); SelectGroup(info.RowHandle, !selected); } } private void View_CustomDrawColumnHeader(object sender, ColumnHeaderCustomDrawEventArgs e) { if (ReferenceEquals(e.Column, _CheckColumn)) { e.Info.InnerElements.Clear(); e.Painter.DrawObject(e.Info); var gray = (SelectedCount > 0) & (SelectedCount < View.DataRowCount); DrawCheckBox(e.Graphics, e.Bounds, SelectedCount == View.DataRowCount, gray); e.Handled = true; } } private void View_CustomDrawGroupRow(object sender, RowObjectCustomDrawEventArgs e) { var info = default(GridGroupRowInfo); info = (GridGroupRowInfo)e.Info; info.GroupText = " " + info.GroupText.TrimStart(); e.Info.Paint.FillRectangle(e.Graphics, e.Appearance.GetBackBrush(e.Cache), e.Bounds); e.Painter.DrawObject(e.Info); var r = info.ButtonBounds; r.Offset(r.Width * 2, 0); var g = GroupRowSelectionStatus(e.RowHandle); DrawCheckBox(e.Graphics, r, g > 0, g < 0); e.Handled = true; } private void view_CustomUnboundColumnData(object sender, CustomColumnDataEventArgs e) { if (ReferenceEquals(e.Column, CheckMarkColumn)) { if (e.IsGetData) e.Value = IsRowSelected(e.ListSourceRowIndex); else SelectRow(e.ListSourceRowIndex, (bool)e.Value); } } } }