#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
|
{
|
/// <summary>
|
/// C# GridView列头添加CheckBox控件实现全选功能
|
/// by C/S框架网 www.csframework.com
|
/// </summary>
|
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;
|
|
/// <summary>
|
/// 勾选的记录数
|
/// </summary>
|
private int SelectedCount => _CheckedRows.Count;
|
|
/// <summary>
|
/// 返回过滤后的实际记录数
|
/// </summary>
|
public int SelectedCountReal
|
{
|
get
|
{
|
var dt = SelectedTable;
|
return dt == null ? 0 : dt.Rows.Count;
|
}
|
}
|
|
/// <summary>
|
/// 返回过滤后勾选的表
|
/// </summary>
|
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;
|
}
|
}
|
|
/// <summary>
|
/// 勾选的记录
|
/// </summary>
|
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("~", ".");
|
}
|
|
/// <summary>
|
/// 创建菜单项DXMenuItem
|
/// </summary>
|
/// <param name="owner">GridViewMenu</param>
|
/// <param name="caption">菜单标题</param>
|
/// <param name="image">菜单图片</param>
|
/// <param name="clickEvent">Click 事件</param>
|
/// <param name="beginGroup"></param>
|
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();
|
}
|
|
/// <summary>
|
/// 过滤表.GridView.ActiveFilterString
|
/// </summary>
|
/// <param name="checkedTable">勾选的表</param>
|
/// <returns></returns>
|
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<DataRow>();
|
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);
|
}
|
}
|
}
|
}
|