using DevExpress.Utils;
using DevExpress.Utils.Menu;
using DevExpress.Utils.Svg;
using DevExpress.XtraBars;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid.Views.Grid;
using DxHelper;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ListView;
public static class GridControlEx
{
class GridTag
{
public GridTag() { }
public PopupMenu PopupMenu { get; set; }
public BarManager BarM { get; set; }
}
///
/// 初始化表格(默认禁用分组)
///
///
/// 绑定的数据源
/// 行高(默认24px)
/// 是否显示水平滚动条(默认不显示)
/// 绑定的数据源模型类型
///
public static GridControl UseDefault(this GridControl grid,List dataSource, int rowHeight = 24, bool showScrollH = false)
{
grid.DataSource = dataSource;
grid.MainView.BorderStyle = BorderStyles.Flat;
var view = grid.MainView as GridView;
view.CustomColumnDisplayText += View_CustomColumnDisplayText;
view.Appearance.HeaderPanel.TextOptions.HAlignment = HorzAlignment.Center;
view.Appearance.Row.Options.UseTextOptions = true;
view.Appearance.Row.TextOptions.HAlignment = HorzAlignment.Center;
view.OptionsView.ColumnHeaderAutoHeight = DefaultBoolean.True;
view.RowHeight = rowHeight;
view.OptionsView.ShowGroupPanel = false;
view.OptionsBehavior.Editable = false;
view.OptionsView.ShowDetailButtons = false;
view.OptionsView.ShowIndicator = false;
view.OptionsMenu.EnableColumnMenu = true;
view.OptionsCustomization.AllowFilter = true;
view.OptionsCustomization.AllowGroup = false;
view.OptionsCustomization.AllowSort = true;
view.OptionsCustomization.AllowColumnMoving = true;
view.OptionsCustomization.AllowMergedGrouping = DefaultBoolean.False;
view.OptionsSelection.MultiSelect = false;
view.OptionsCustomization.AllowRowSizing = false;
view.OptionsCustomization.AllowQuickHideColumns = false;
view.OptionsMenu.EnableGroupPanelMenu = false;
view.OptionsMenu.EnableGroupRowMenu = false;
view.OptionsMenu.EnableFooterMenu = false;
view.OptionsLayout.StoreAllOptions = true;
view.OptionsLayout.StoreAppearance = true;
view.OptionsLayout.StoreDataSettings = true;
view.OptionsLayout.StoreVisualOptions = true;
view.OptionsLayout.StoreFormatRules = true;
view.OptionsView.ColumnAutoWidth = !showScrollH;
view.PopupMenuShowing += View_PopupMenuShowing;
view.OptionsSelection.EnableAppearanceFocusedCell = false;
string GetLayoutName()
{
Control ctrl;
if (view.Tag is SearchLookUpEdit searchLookUpEdit)
ctrl = searchLookUpEdit;
else
ctrl = grid;
while (ctrl.Parent != null)
{
ctrl = ctrl.Parent;
if (ctrl is UserControl) break;
}
var props = typeof(T).GetProperties();
StringBuilder sb = new StringBuilder();
foreach (var item in props)
{
sb.Append(item.Name);
}
var md5 = MD5Helper.StrToMD5(sb.ToString());
if (view.Tag is SearchLookUpEdit searchLookUpEdit2)
return $"{ctrl.Name}_{searchLookUpEdit2.Name}_{md5}";
else
return $"{ctrl.Name}_{grid.Name}_{md5}";
}
string name = GetLayoutName();
void SaveLayoutAction()
{
Form frm = null;
if (view.Tag is SearchLookUpEdit edit)
frm = edit.FindForm();
else
frm = grid.FindForm();
if (frm != null)
{
frm.VisibleChanged += (sender2, e2) =>
{
Directory.CreateDirectory("Layout");
if (name == null) return;
grid.MainView?.SaveLayoutToXml($"Layout\\{name}.xml", OptionsLayoutBase.FullLayout);
};
}
}
if (grid.IsLoaded)
{
SaveLayoutAction();
}
else
{
grid.Load += (sender, e) => SaveLayoutAction();
}
if (name != null && File.Exists($"Layout\\{name}.xml"))
{
view.RestoreLayoutFromXml($"Layout\\{name}.xml", OptionsLayoutBase.FullLayout);
}
view.KeyUp += View_KeyUp;
grid.Tag = new GridTag();
return grid;
}
///
/// 为GirdControl启用右键新增数据的功能
///
///
///
///
/// 一个回调函数,返回新增的数据
///
public static GridControl UseAdd(this GridControl grid, Func callback, string menuCaption = "新增")
{
var view = grid.MainView as GridView;
view.CustomDrawEmptyForeground += (sender, e) =>
{
string emptyText = "右键添加";
var s = e.Appearance.CalcTextSize(e.Cache, emptyText, e.Bounds.Width).ToSize();
var x = (e.Bounds.Width - s.Width) / 2;
var y = (e.Bounds.Height - s.Height) / 2;
e.Appearance.ForeColor = Color.Gray;
e.Appearance.DrawString(e.Cache, emptyText, new Rectangle(x, y, s.Width, s.Height));
};
grid.AddContentMenu(menuCaption, DxHelper.SvgHelper.CreateAdd(), data =>
{
if (callback != null)
{
var addRow = callback();
if (addRow == null) return;
var ds = grid.DataSource as List;
ds.Add(addRow);
view.RefreshData();
}
}, true);
return grid;
}
///
/// 为GirdControl启用右键新增数据的功能
///
///
///
///
/// 一个回调函数,返回新增的数据
///
public static GridControl UseAddAsync(this GridControl grid, Func> callback, string menuCaption = "新增")
{
grid.AddContentMenu(menuCaption, DxHelper.SvgHelper.CreateAdd(), async data =>
{
if (callback != null)
{
var addRow = await callback();
if (addRow == null) return;
var view = grid.MainView as GridView;
var ds = grid.DataSource as List;
ds.Add(addRow);
view.RefreshData();
}
}, true);
return grid;
}
///
/// 为GridControl启用右编辑选中的单行功能
///
///
///
///
///
///
public static GridControl UseEdit(this GridControl grid, Func callback, string menuCaption = "编辑")
{
grid.AddRowMenu(menuCaption, DxHelper.SvgHelper.CreateEdit(), data =>
{
if (callback != null)
{
var newRow = callback(data);
if (newRow == null) return;
var view = grid.MainView as GridView;
var ds = grid.DataSource as List;
var idx = ds.IndexOf(data);
ds.Remove(data);
ds.Insert(idx, newRow);
view.RefreshData();
}
}, null);
return grid;
}
///
/// 为GridControl启用右编辑选中的单行功能
///
///
///
///
///
///
public static GridControl UseEditAsync(this GridControl grid, Func> callback, string menuCaption = "编辑")
{
grid.AddRowMenu(menuCaption, DxHelper.SvgHelper.CreateEdit(), async data =>
{
if (callback != null)
{
var newRow = await callback(data);
if (newRow == null) return;
var view = grid.MainView as GridView;
var ds = grid.DataSource as List;
var idx = ds.IndexOf(data);
ds.Remove(data);
ds.Insert(idx, newRow);
view.RefreshData();
}
}, null);
return grid;
}
///
/// 为GridControl启用右删除选中的一行或多行功能(自动启用UseMultiSelect)
///
///
///
///
///
///
public static GridControl UseDelete(this GridControl grid, Func, bool> action = null, string menuCaption = "删除")
{
grid.AddMultRowMenu(menuCaption, DxHelper.SvgHelper.CreateClose(), data =>
{
if (!DxHelper.MsgBoxHelper.ShowConfirm($"确认删除选中的记录?共[{data.Count}]条")) return;
if (action != null)
{
bool succeed = action(data);
if (!succeed) return;
}
var view = grid.MainView as GridView;
view.DeleteSelectedRows();
view.RefreshData();
});
return grid;
}
///
/// 为GridControl启用右删除选中的一行或多行功能(自动启用UseMultiSelect)
///
///
///
///
///
///
public static GridControl UseDeleteAsync(this GridControl grid, Func, Task> action = null, string menuCaption = "删除")
{
grid.AddMultRowMenu(menuCaption, DxHelper.SvgHelper.CreateClose(), async data =>
{
if (!DxHelper.MsgBoxHelper.ShowConfirm($"确认删除选中的记录?共[{data.Count()}]条")) return;
if (action != null)
{
bool succeed = await action(data);
if (!succeed) return;
}
var view = grid.MainView as GridView;
view.DeleteSelectedRows();
view.RefreshData();
});
return grid;
}
///
/// 为GirdControl启用右键清除所有数据的功能
///
///
///
///
///
///
public static GridControl UseClear(this GridControl grid, Func, bool> action = null, string menuCaption = "清除")
{
grid.AddContentMenu(menuCaption, DxHelper.SvgHelper.CreateClear(), data =>
{
if (data == null || data.Count == 0) return;
if (!DxHelper.MsgBoxHelper.ShowConfirm($"确认清空所有记录?共[{data.Count}]条")) return;
if (action != null)
{
bool succeed = action(data);
if (!succeed) return;
}
var view = grid.MainView as GridView;
data.Clear();
view.RefreshData();
}, false);
return grid;
}
///
/// 为GirdControl启用右键清除所有数据的功能
///
///
///
///
///
///
public static GridControl UseClearAsync(this GridControl grid, Func, Task> action = null, string menuCaption = "清除")
{
grid.AddContentMenu(menuCaption, DxHelper.SvgHelper.CreateClear(), async data =>
{
if (data == null || data.Count == 0) return;
if (!DxHelper.MsgBoxHelper.ShowConfirm($"确认清空所有记录?共[{data.Count}]条")) return;
if (action != null)
{
bool succeed = await action(data);
if (!succeed) return;
}
var view = grid.MainView as GridView;
data.Clear();
view.RefreshData();
}, false);
return grid;
}
public static GridControl UseExportCsv(this GridControl grid)
{
GridTag tag = grid.Tag as GridTag;
if (tag.BarM == null)
{
tag.BarM = new BarManager();
tag.BarM.Form = grid;
}
if (tag.PopupMenu == null)
{
tag.PopupMenu = new PopupMenu();
}
PopupMenu popupMenu = tag.PopupMenu;
BarButtonItem item = new BarButtonItem();
item.ItemClick += (sender, e) =>
{
SaveFileDialog dialog = new SaveFileDialog();
dialog.Filter = "csv|*.csv";
if (dialog.ShowDialog() == DialogResult.OK)
{
var view = grid.MainView as GridView;
view.ExportToCsv(dialog.FileName);
}
};
item.ImageOptions.SvgImage = DxHelper.SvgHelper.CreateExportCsv();
item.Caption = "导出(CSV)";
tag.BarM.Items.Add(item);
popupMenu.AddItem(item);
popupMenu.Manager = tag.BarM;
tag.PopupMenu = popupMenu;
return grid;
}
public static GridControl UseExportXlsx(this GridControl grid)
{
GridTag tag = grid.Tag as GridTag;
if (tag.BarM == null)
{
tag.BarM = new BarManager();
tag.BarM.Form = grid;
}
if (tag.PopupMenu == null)
{
tag.PopupMenu = new PopupMenu();
}
PopupMenu popupMenu = tag.PopupMenu;
BarButtonItem item = new BarButtonItem();
item.ItemClick += (sender, e) =>
{
SaveFileDialog dialog = new SaveFileDialog();
dialog.Filter = "Excel文件|*.xlsx";
if (dialog.ShowDialog() == DialogResult.OK)
{
var view = grid.MainView as GridView;
view.ExportToXlsx(dialog.FileName);
}
};
item.ImageOptions.SvgImage = DxHelper.SvgHelper.CreateExportXlsx();
item.Caption = "导出(Excel)";
tag.BarM.Items.Add(item);
popupMenu.AddItem(item);
popupMenu.Manager = tag.BarM;
tag.PopupMenu = popupMenu;
return grid;
}
private static void View_KeyUp(object sender, KeyEventArgs e)
{
if (e.Control && e.Shift & e.KeyCode == Keys.C)
{
var view = sender as GridView;
if (view.FocusedColumn == null) return;
var val = view.GetFocusedRowCellDisplayText(view.FocusedColumn);
if (string.IsNullOrWhiteSpace(val)) return;
Clipboard.SetText(val);
}
}
private static void View_CustomColumnDisplayText(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDisplayTextEventArgs e)
{
if (e.Column.ColumnType == typeof(DateTime) || e.Column.ColumnType == typeof(DateTime?))
{
if (e.Value == null) return;
if (e.Column.FieldName == "SigTime")
e.DisplayText = Convert.ToDateTime(e.Value).ToString("yyyy-MM-dd HH:mm:ss.fff");
else
e.DisplayText = Convert.ToDateTime(e.Value).ToString("yyyy-MM-dd HH:mm:ss");
}
}
public static GridControl ShowColumn(this GridControl grid, params string[] colField)
{
var view = grid.MainView as GridView;
if (view.Columns.Count == 0) return grid;
if (colField == null || colField.Length == 0) return grid;
foreach (GridColumn item in view.Columns)
{
if (colField.Contains(item.FieldName))
item.Visible = true;
}
return grid;
}
public static GridControl UseMultiSelect(this GridControl grid)
{
var view = grid.MainView as GridView;
view.OptionsSelection.MultiSelect = true;
view.OptionsSelection.MultiSelectMode = GridMultiSelectMode.RowSelect;
return grid;
}
public static GridControl UseGroup(this GridControl grid)
{
var view = grid.MainView as GridView;
view.OptionsView.GroupFooterShowMode = GroupFooterShowMode.Hidden;
view.OptionsView.ShowGroupPanel = true;
view.OptionsCustomization.AllowGroup = true;
view.OptionsCustomization.AllowSort = true;
return grid;
}
public static GridControl UseFooter(this GridControl grid, Action