using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using ProjectBase.Data.Pager;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid.Views.Grid;
using System.IO;
using DevExpress.Utils;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using ProjectBase.Controls.Others;
using System.Diagnostics;
namespace ProjectBase.Controls
{
///
/// 带分页导航的分页控件
///
public partial class WinGridViewPager : DevExpress.XtraEditors.XtraUserControl
{
///
/// 是否显示CheckBox列
///
public bool ShowCheckBox { get; set; }
private object dataSource;//数据源
private string displayColumns = "";//显示的列
private string printTitle = "";//报表标题
private Dictionary columnDict = new Dictionary();//字段列顺序
private PagerInfo pagerInfo = null;
private SaveFileDialog saveFileDialog = new SaveFileDialog();
private bool isExportAllPage = false;//是否导出所有页
private Dictionary columnNameAlias = new Dictionary();//字段别名字典集合
private ContextMenuStrip appendedMenu;//右键菜单
private bool m_ShowExportButton = true;//是否显示导出按钮
private bool m_ShowAddMenu = true;//是否显示新建菜单
private bool m_ShowEditMenu = true;//是否显示编辑菜单
private bool m_ShowDeleteMenu = true;//是否显示删除菜单
#region 菜单显示文本
///
/// 新建菜单的显示内容
///
public string AddMenuText = "新建(&N)";
///
/// 编辑菜单的显示内容
///
public string EditMenuText = "编辑选定项(&E)";
///
/// 删除菜单的显示内容
///
public string DeleteMenuText = "删除选定项(&D)";
///
/// 刷新菜单的显示内容
///
public string RefreshMenuText = "刷新列表(&R)";
#endregion
///
/// 导出全部的数据源
///
public object AllToExport;
///
/// 是否显示行号
///
public bool ShowLineNumber = false;
///
/// 获取或设置奇数行的背景色
///
public Color EventRowBackColor = Color.LightCyan;
///
/// 是否使用最佳宽度
///
public bool BestFitColumnWith = true;
///
/// 冻结列的固定样式,默认为左边
///
public FixedStyle Fixed = FixedStyle.Left;
///
/// 冻结列的字段,多个字段逗号分开
///
public string FixedColumns { get; set; }
#region 权限功能控制
///
/// 是否显示导出按钮
///
[Category("分页"), Description("是否显示导出按钮。"), Browsable(true)]
public bool ShowExportButton
{
get { return m_ShowExportButton; }
set
{
m_ShowExportButton = value;
if (this.pager != null)
{
this.pager.ShowExportButton = this.ShowExportButton;
}
}
}
///
/// 是否显示新建菜单
///
[Category("分页"), Description("是否显示新建菜单。"), Browsable(true)]
public bool ShowAddMenu
{
get { return m_ShowAddMenu; }
set { m_ShowAddMenu = value; }
}
///
/// 是否显示编辑菜单
///
[Category("分页"), Description("是否显示编辑菜单。"), Browsable(true)]
public bool ShowEditMenu
{
get { return m_ShowEditMenu; }
set { m_ShowEditMenu = value; }
}
///
/// 是否显示删除菜单
///
[Category("分页"), Description("是否显示删除菜单。"), Browsable(true)]
public bool ShowDeleteMenu
{
get { return m_ShowDeleteMenu; }
set { m_ShowDeleteMenu = value; }
}
#endregion
///
/// 列名的别名字典集合
///
public Dictionary ColumnNameAlias
{
get { return columnNameAlias; }
set
{
if (value != null)
{
foreach (string key in value.Keys)
{
AddColumnAlias(key, value[key]);
}
}
}
}
#region 事件处理
///
/// 导出Excel前执行的操作
///
public event EventHandler OnStartExport;
///
/// 导出Excel后执行的操作
///
public event EventHandler OnEndExport;
///
/// 页面变化的操作
///
public event EventHandler OnPageChanged;
///
/// 双击控件实现的操作,实现后出现右键菜单“编辑选定项”
///
public event EventHandler OnEditSelected;
///
/// 实现事件后出现“删除选定项”菜单项
///
public event EventHandler OnDeleteSelected;
///
/// 实现事件后出现“更新”菜单项
///
public event EventHandler OnRefresh;
///
/// 实现事件后,出现“新建”菜单项
///
public event EventHandler OnAddNew;
///
/// 实现对单击GirdView控件的响应
///
public event EventHandler OnGridViewMouseClick;
///
/// 实现对双击GirdView控件的响应
///
public event EventHandler OnGridViewMouseDoubleClick;
///
/// 实现对复选框选择变化的响应
///
public event SelectionChangedEventHandler OnCheckBoxSelectionChanged;
#endregion
///
/// 追加的菜单项目
///
public ContextMenuStrip AppendedMenu
{
get
{
return appendedMenu;
}
set
{
if (value != null)
{
appendedMenu = value;
for (int i = 0; appendedMenu.Items.Count > 0; i++)
{
this.contextMenuStrip1.Items.Insert(i, appendedMenu.Items[0]);
}
}
}
}
///
/// 构造函数
///
public WinGridViewPager()
{
InitializeComponent();
}
private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
{
this.menu_Add.Visible = (this.OnAddNew != null && this.ShowAddMenu);
this.menu_Delete.Visible = (this.OnDeleteSelected != null && this.ShowDeleteMenu);
this.menu_Edit.Visible = (this.OnEditSelected != null && this.ShowEditMenu);
this.menu_Refresh.Visible = (this.OnRefresh != null);
this.menu_Add.Text = AddMenuText;
this.menu_Edit.Text = EditMenuText;
this.menu_Delete.Text = DeleteMenuText;
this.menu_Refresh.Text = RefreshMenuText;
}
///
/// 封装的GridView对象
///
public GridView GridView1
{
get
{
return this.gridView1;
}
}
private void pager_PageChanged(object sender, EventArgs e)
{
if (OnPageChanged != null)
{
OnPageChanged(this, new EventArgs());
}
}
///
/// 获取或设置数据源
///
public object DataSource
{
get { return dataSource; }
set
{
if (this.gridView1.Columns != null)
{
this.gridView1.Columns.Clear();
}
dataSource = value;
this.gridControl1.DataSource = dataSource;
this.pager.InitPageInfo(PagerInfo.RecordCount, PagerInfo.PageSize);
}
}
private Dictionary GetColumnNameTypes(DataTable dt)
{
Dictionary dict = new Dictionary();
foreach (DataColumn col in dt.Columns)
{
if (!dict.ContainsKey(col.ColumnName))
{
dict.Add(col.ColumnName, col.DataType.FullName);
}
}
return dict;
}
///
/// 显示的列内容,需要指定以防止GridView乱序
/// 使用"|"或者","分开每个列,如“ID|Name”
///
public string DisplayColumns
{
get { return displayColumns; }
set
{
displayColumns = value;
columnDict = new Dictionary();
string[] items = displayColumns.Split(new char[] { '|', ',' });
for (int i = 0; i < items.Length; i++)
{
string str = items[i];
if (!string.IsNullOrEmpty(str))
{
str = str.Trim();
if (!columnDict.ContainsKey(str.ToUpper()))
{
columnDict.Add(str.ToUpper(), i);
}
}
}
}
}
///
/// 返回对应字段的显示顺序,如果没有,返回-1
///
///
///
private int GetDisplayColumnIndex(string columnName)
{
int result = -1;
if (columnDict.ContainsKey(columnName.ToUpper()))
{
result = columnDict[columnName.ToUpper()];
}
return result;
}
///
/// 添加列名的别名
///
/// 列的原始名称
/// 列的别名
public void AddColumnAlias(string key, string alias)
{
if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(alias))
{
if (!columnNameAlias.ContainsKey(key.ToUpper()))
{
columnNameAlias.Add(key.ToUpper(), alias);
}
else
{
columnNameAlias[key.ToUpper()] = alias;
}
}
}
///
/// 分页信息
///
public PagerInfo PagerInfo
{
get
{
if (pagerInfo == null)
{
pagerInfo = new PagerInfo();
pagerInfo.RecordCount = this.pager.RecordCount;
pagerInfo.CurrenetPageIndex = this.pager.CurrentPageIndex;
pagerInfo.PageSize = this.pager.PageSize;
}
else
{
pagerInfo.CurrenetPageIndex = this.pager.CurrentPageIndex;
}
return pagerInfo;
}
}
///
/// 打印报表的抬头(标题)
///
public string PrintTitle
{
get { return printTitle; }
set { printTitle = value; }
}
///
/// 导出所有记录的事件
///
private void pager_ExportAll(object sender, EventArgs e)
{
isExportAllPage = true;
ExportToExcel();
}
///
/// 导出当前页记录的事件
///
private void pager_ExportCurrent(object sender, EventArgs e)
{
isExportAllPage = false;
ExportToExcel();
}
#region 导出Excel操作
private void ExportToExcel()
{
saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "Excel (*.xls)|*.xls";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
if (!saveFileDialog.FileName.Equals(String.Empty))
{
FileInfo f = new FileInfo(saveFileDialog.FileName);
if (f.Extension.ToLower().Equals(".xls"))
{
StartExport(saveFileDialog.FileName);
}
else
{
MessageBox.Show("文件格式不正确");
}
}
else
{
MessageBox.Show("需要指定一个保存的目录");
}
}
}
///
/// starts the export to new excel document
///
/// the file to export to
private void StartExport(String filepath)
{
if (OnStartExport != null)
{
OnStartExport(this, new EventArgs());
}
BackgroundWorker bg = new BackgroundWorker();
bg.DoWork += new DoWorkEventHandler(bg_DoWork);
bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted);
bg.RunWorkerAsync(filepath);
}
///
/// 使用背景线程导出Excel文档
///
private void bg_DoWork(object sender, DoWorkEventArgs e)
{
DataTable table = new DataTable();
if (AllToExport != null && isExportAllPage)
{
if (AllToExport is DataView)
{
DataView dv = (DataView)AllToExport;//默认导出显示内容
table = dv.ToTable();
}
else if (AllToExport is DataTable)
{
table = AllToExport as DataTable;
}
else
{
table = ReflectionUtil.CreateTable(AllToExport);
}
//解析标题
string originalName = string.Empty;
foreach (DataColumn column in table.Columns)
{
originalName = column.Caption;
if (columnNameAlias.ContainsKey(originalName.ToUpper()))
{
column.Caption = columnNameAlias[originalName.ToUpper()];
column.ColumnName = columnNameAlias[originalName.ToUpper()];
}
}
//for (int i = 0; i < this.gridView1.Columns.Count; i++)
//{
// if (!this.gridView1.Columns[i].Visible)
// {
// table.Columns.Remove(this.gridView1.Columns[i].FieldName);
// }
//}
}
else
{
DataColumn column;
DataRow row;
for (int i = 0; i < this.gridView1.Columns.Count; i++)
{
if (this.gridView1.Columns[i].Visible)
{
column = new DataColumn(this.gridView1.Columns[i].FieldName, typeof(string));
column.Caption = this.gridView1.Columns[i].Caption;
table.Columns.Add(column);
}
}
object cellValue = "";
string fieldName = "";
for (int i = 0; i < gridView1.RowCount; i++)
{
row = table.NewRow();
for (int j = 0; j < gridView1.Columns.Count; j++)
{
if (this.gridView1.Columns[j].Visible)
{
fieldName = gridView1.Columns[j].FieldName;
cellValue = gridView1.GetRowCellValue(i, fieldName);
row[fieldName] = cellValue ?? "";
}
}
table.Rows.Add(row);
}
}
string outError = "";
AsposeExcelTools.DataTableToExcel2(table, (String)e.Argument, out outError);
}
//show a message to the user when the background worker has finished
//and re-enable the export buttons
private void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (OnEndExport != null)
{
OnEndExport(this, new EventArgs());
}
if (MessageBox.Show("导出操作完成, 您想打开该Excel文件么?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
{
Process.Start(saveFileDialog.FileName);
}
}
#endregion
#region 菜单操作
private void menu_Delete_Click(object sender, EventArgs e)
{
if (OnDeleteSelected != null && this.ShowDeleteMenu)
{
OnDeleteSelected(this.gridView1, new EventArgs());
}
}
private void menu_Refresh_Click(object sender, EventArgs e)
{
if (this.OnRefresh != null)
{
OnRefresh(this.gridView1, new EventArgs());
}
}
private void menu_Edit_Click(object sender, EventArgs e)
{
if (OnEditSelected != null && this.ShowEditMenu)
{
OnEditSelected(this.gridView1, new EventArgs());
}
}
private void menu_Print_Click(object sender, EventArgs e)
{
PrintDGV.Print_GridView(this.gridView1, this.printTitle);
}
private void menu_Add_Click(object sender, EventArgs e)
{
if (this.OnAddNew != null && this.ShowAddMenu)
{
this.OnAddNew(this.gridView1, new EventArgs());
}
}
private void menu_CopyInfo_Click(object sender, EventArgs e)
{
int[] selectedRow = this.gridView1.GetSelectedRows();
if (selectedRow == null || selectedRow.Length == 0)
return;
StringBuilder sbHeader = new StringBuilder();
StringBuilder sb = new StringBuilder();
if (selectedRow.Length == 1)
{
//单行复制的时候
foreach (GridColumn gridCol in this.gridView1.Columns)
{
if (gridCol.Visible)
{
sbHeader.AppendFormat("{0}:{1} \r\n", gridCol.Caption, this.gridView1.GetRowCellDisplayText(selectedRow[0], gridCol.FieldName));
}
}
sb.AppendLine();
}
else
{
//多行复制的时候
foreach (GridColumn gridCol in this.gridView1.Columns)
{
if (gridCol.Visible)
{
sbHeader.AppendFormat("{0}\t", gridCol.Caption);
}
}
foreach (int row in selectedRow)
{
foreach (GridColumn gridCol in this.gridView1.Columns)
{
if (gridCol.Visible)
{
sb.AppendFormat("{0}\t", this.gridView1.GetRowCellDisplayText(row, gridCol.FieldName));
}
}
sb.AppendLine();
}
}
Clipboard.SetText(sbHeader.ToString() + "\r\n" + sb.ToString());
}
private void menu_SetColumn_Click(object sender, EventArgs e)
{
FrmSelectColumnDisplay dlg = new FrmSelectColumnDisplay();
dlg.DisplayColumNames = this.displayColumns;
dlg.ColumnNameAlias = columnNameAlias;
dlg.DataGridView = this.gridView1;
dlg.ShowDialog();
}
#endregion
private void gridView1_DataSourceChanged(object sender, EventArgs e)
{
#region 修改别名及可见
//先判断设置显示的列(如果没有则显示全部)
string originalName = string.Empty;
string tempColumns = string.Empty;
if (string.IsNullOrEmpty(this.DisplayColumns))
{
for (int i = 0; i < this.gridView1.Columns.Count; i++)
{
originalName = this.gridView1.Columns[i].FieldName;
tempColumns += string.Format("{0},", originalName);
}
tempColumns = tempColumns.Trim(',');
this.DisplayColumns = tempColumns;//全部显示
}
//转换为大写列表
List fixedList = new List();
if (!string.IsNullOrEmpty(FixedColumns))
{
fixedList = FixedColumns.ToUpper().ToDelimitedList(",");
}
//字段的排序顺序,先记录(使用排序的字典)
SortedDictionary colIndexList = new SortedDictionary();
foreach (GridColumn col in this.gridView1.Columns)
{
//设置列标题
originalName = col.FieldName;
if (columnNameAlias.ContainsKey(originalName.ToUpper()))
{
col.Caption = columnNameAlias[originalName.ToUpper()];
}
else
{
col.Caption = originalName;//如果没有别名用原始字段名称,如ID
}
//设置不显示字段
if (!columnDict.ContainsKey(originalName.ToUpper()))
{
col.Visible = false;
}
//这里先记录每个字段名称,以及它的真实顺序位置
//col.VisibleIndex = GetDisplayColumnIndex(originalName.ToUpper());
int VisibleIndex = GetDisplayColumnIndex(originalName.ToUpper());
if (VisibleIndex == -1)
{
//如果是不显示的,则设置可见顺序为-1
col.VisibleIndex = VisibleIndex;
}
else
{
//否则记录起来后面一并按顺序设置
if (!colIndexList.ContainsKey(VisibleIndex))
{
colIndexList.Add(VisibleIndex, originalName);
}
}
}
//统一设置所有可见的字段顺序
foreach (int index in colIndexList.Keys)
{
originalName = colIndexList[index];
this.gridView1.Columns[originalName].VisibleIndex = index;
}
//设置列固定(大写判断)
for (int i = 0; i < this.gridView1.VisibleColumns.Count; i++)
{
GridColumn col = this.gridView1.VisibleColumns[i];
originalName = col.FieldName;
if (fixedList != null && fixedList.Contains(originalName.ToUpper()))
{
col.Fixed = Fixed;
}
}
#endregion
#region 设置特殊内容显示
object cellValue = "";
string fieldName = "";
for (int i = 0; i < gridView1.RowCount; i++)
{
for (int j = 0; j < gridView1.Columns.Count; j++)
{
fieldName = gridView1.Columns[j].FieldName;
cellValue = gridView1.GetRowCellValue(i, fieldName);
if (cellValue != null && cellValue.GetType() == typeof(DateTime))
{
if (cellValue != DBNull.Value)
{
DateTime dtTemp = DateTime.MinValue;
DateTime.TryParse(cellValue.ToString(), out dtTemp);
TimeSpan ts = dtTemp.Subtract(Convert.ToDateTime("1753/1/1"));
if (ts.TotalDays < 1)
{
gridView1.SetRowCellValue(i, fieldName, DBNull.Value);
}
}
}
}
}
#endregion
if (this.ShowLineNumber)
{
this.gridView1.IndicatorWidth = 40;
}
this.gridView1.OptionsView.ColumnAutoWidth = BestFitColumnWith;
if (BestFitColumnWith)
{
this.gridView1.BestFitColumns();
}
if (ShowCheckBox)
{
GridCheckMarksSelection selection = new GridCheckMarksSelection(gridView1);
selection.CheckMarkColumn.VisibleIndex = 0;
selection.CheckMarkColumn.Width = 60;
selection.SelectionChanged += new SelectionChangedEventHandler(selection_SelectionChanged);
this.gridView1.OptionsBehavior.Editable = true;
this.gridView1.OptionsBehavior.ReadOnly = false;
}
}
void selection_SelectionChanged(object sender, EventArgs e)
{
if (this.OnCheckBoxSelectionChanged != null)
{
this.OnCheckBoxSelectionChanged(sender, e);
}
}
///
/// 获取勾选上的行索引列表
///
///
public List GetCheckedRows()
{
List list = new List();
if (this.ShowCheckBox)
{
for (int rowIndex = 0; rowIndex < this.gridView1.RowCount; rowIndex++)
{
object objValue = this.gridView1.GetRowCellValue(rowIndex, "CheckMarkSelection");
if (objValue != null)
{
bool check = false;
bool.TryParse(objValue.ToString(), out check);
if (check)
{
list.Add(rowIndex);
}
}
}
}
return list;
}
private void dataGridView1_MouseClick(object sender, MouseEventArgs e)
{
if (OnGridViewMouseClick != null)
{
OnGridViewMouseClick(sender, e);
}
}
private void dataGridView1_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (this.OnEditSelected != null && this.ShowEditMenu)
{
this.OnEditSelected(this.gridView1, new EventArgs());
}
else if (OnGridViewMouseDoubleClick != null)
{
OnGridViewMouseDoubleClick(this.gridView1, new EventArgs());
}
}
private void toolTipController1_GetActiveObjectInfo(object sender, DevExpress.Utils.ToolTipControllerGetActiveObjectInfoEventArgs e)
{
if (e.SelectedControl != gridControl1) return;
ToolTipControlInfo info = null;
//Get the view at the current mouse position
GridView view = gridControl1.GetViewAt(e.ControlMousePosition) as GridView;
if (view == null) return;
//Get the view's element information that resides at the current position
GridHitInfo hi = view.CalcHitInfo(e.ControlMousePosition);
//Display a hint for row indicator cells
if (hi.HitTest == GridHitTest.RowIndicator)
{
//An object that uniquely identifies a row indicator cell
object o = hi.HitTest.ToString() + hi.RowHandle.ToString();
StringBuilder sb = new StringBuilder();
sb.AppendLine("行数据基本信息:");
foreach (GridColumn gridCol in view.Columns)
{
if (gridCol.Visible)
{
sb.AppendFormat(" {0}:{1}\r\n", gridCol.Caption, view.GetRowCellDisplayText(hi.RowHandle, gridCol.FieldName));
}
}
info = new ToolTipControlInfo(o, sb.ToString());
}
//Supply tooltip information if applicable, otherwise preserve default tooltip (if any)
if (info != null)
{
e.Info = info;
}
}
private void gridView1_CustomDrawRowIndicator(object sender, RowIndicatorCustomDrawEventArgs e)
{
if (ShowLineNumber)
{
e.Appearance.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Far;
if (e.Info.IsRowIndicator)
{
if (e.RowHandle >= 0)
{
e.Info.DisplayText = (e.RowHandle + 1).ToString();
}
}
}
}
private void WinGridViewPager_Load(object sender, EventArgs e)
{
if (!this.DesignMode)
{
this.pager.PageChanged += new PageChangedEventHandler(pager_PageChanged);
this.pager.ExportCurrent += new ExportCurrentEventHandler(pager_ExportCurrent);
this.pager.ExportAll += new ExportAllEventHandler(pager_ExportAll);
this.contextMenuStrip1.Opening += new CancelEventHandler(contextMenuStrip1_Opening);
this.gridControl1.MouseClick += new MouseEventHandler(dataGridView1_MouseClick);
this.gridControl1.MouseDoubleClick += new MouseEventHandler(dataGridView1_MouseDoubleClick);
this.gridView1.Appearance.EvenRow.BackColor = EventRowBackColor;
}
}
private void menu_ColumnWidth_Click(object sender, EventArgs e)
{
this.BestFitColumnWith = !this.BestFitColumnWith;
ShowWidthStatus();
if (OnRefresh != null)
{
OnRefresh(sender, e);
}
}
private void ShowWidthStatus()
{
if (this.BestFitColumnWith)
{
this.menu_ColumnWidth.Text = "设置列固定宽度(&W)";
}
else
{
this.menu_ColumnWidth.Text = "设置列自动适应宽度(&W)";
}
}
}
}