#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);
}
}
}
}