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