2024年终活动

DevExpress控件使用交流,DevExpress中国社区Dev联系电话 联系电话:023-68661681

【干货分享】一些基于DevExpress GridControl实现的界面处理功能(下)

来源:   发布时间:2023-06-02   浏览:1823次

DevExpress的GridControl控件能够提供很多强大的操作,其视图GridView能够通过各种设置,呈现出多种复杂的界面效果,本篇随笔探讨一些常见的GridControl控件及其GridView的视图操作处理,以便在大家也需要的时候作为一个参考的代码。其中设计一些常见的操作,如合并单元格、汇总统计、复制粘贴行、导入数据处理、导出Excel、导出PDF等、打印GridView视图、内置插入及保存数据处理等等。

在上文中(点击这里回顾>> )我们为大家讲解了如何合并单元格、汇总统计处理、内置的导出Excel处理等,本文中将继续讲解如何打印当前GridView视图、弹出GridView自定义菜单等。

点击获取DevExpress v22.1正式版

DevExpress技术交流群8:523159565      欢迎一起进群讨论

五、打印当前GridView视图

GridView本身也提供了直接打印的操作方法,如果对一些简单的表格,可以直接使用它进行打印当前视图处理。

currentView.GridControl.ShowRibbonPrintPreview();

这样的打印效果,呈现出一个Ribbon的报表预览界面,然后直接在上面进行定制打印的格式。

【干货分享】一些基于DevExpress GridControl实现的界面处理功能(上)

或者我们也可以在生成打印预览的时候,指定更多的定制信息,如下界面所示。

private void menu_PrintFixColumn_Click(object sender, EventArgs e)
{
this.winGridViewPager1.gridView1.OptionsPrint.EnableAppearanceEvenRow = true;

using (PrintableComponentLink link = new PrintableComponentLink(new PrintingSystem()))
{
link.Component = this.winGridViewPager1.gridControl1;
link.Landscape = true;
link.PaperKind = System.Drawing.Printing.PaperKind.A3;
link.CreateMarginalHeaderArea += new CreateAreaEventHandler(Link_CreateMarginalHeaderArea);
link.CreateDocument();
link.ShowPreview();
}
}
private void Link_CreateMarginalHeaderArea(object sender, CreateAreaEventArgs e)
{
string title = this.AppInfo.AppUnit + " -- " + "备件信息报表";
PageInfoBrick brick = e.Graph.DrawPageInfo(PageInfo.None, title, Color.DarkBlue,
new RectangleF(0, 0, 100, 21), BorderSide.None);

brick.LineAlignment = BrickAlignment.Center;
brick.Alignment = BrickAlignment.Center;
brick.AutoWidth = true;
brick.Font = new System.Drawing.Font("宋体", 11f, FontStyle.Bold);
}

类似的打印预览的界面效果如下所示。

【干货分享】一些基于DevExpress GridControl实现的界面处理功能(上)

当然我们也可以利用第三方控件的打印处理来实现更多的效果,不过内置的GridView打印操作,基本上也能满足大多数的要求了。

六、弹出GridView自定义菜单

GridView的右键菜单,可以用ContextMenuStrip的常规性菜单控件来定义,我分页控件中就是采用这样的方式,设置比较简单,只需要设置GridCtrol控件的ContextMenuStrip属性即可,如下代码所示。

this.gridControl1.ContextMenuStrip = this.contextMenuStrip1;

并且通过ContextMenuStrip的Opening事件,可以对它进行一定的设置禁用/可用的处理。

this.contextMenuStrip1.Opening += new CancelEventHandler(contextMenuStrip1_Opening);

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

这样就可以对GridView的右键进行绑定及权限的设置处理,类似下面的界面效果所示。

【干货分享】一些基于DevExpress GridControl实现的界面处理功能(上)

虽然利用ContextMenuStrip的传统菜单条,可以很好、方便的实现右键菜单的处理,不过缺点是样式没有随着DevExpress本身的效果变化,如果需要追求一样的样式体验,那么可以考虑使用DevExpress的PopupMenu控件来承载菜单或者Ribbon的一些按钮操作。

PopupMenu控件可以指定Ribbon窗体控件,然后它们右键菜单和Ribbon的按钮集合同样的出现和隐藏。

【干货分享】一些基于DevExpress GridControl实现的界面处理功能(上)

然后在设计模式下设计对应的菜单项目集合。

【干货分享】一些基于DevExpress GridControl实现的界面处理功能(上)

在界面设计好Ribbon的按钮和菜单对象的按钮后,我们可以为菜单绑定对应的GridControl事件处理,让它结合GridControl的右键事件出现右键菜单。

this.gridControl.MouseUp += GridControl_MouseUp;

显示右键菜单的事件代码如下所示。

private void GridControl_MouseUp(object sender, MouseEventArgs e)
{
try
{
if (e.Button == MouseButtons.Right)
{
var view = gridControl.DefaultView as GridView;
var info = view.CalcHitInfo(e.Location);
if (info.InRowCell)
{
popupGridMenu.ShowPopup(gridControl.PointToScreen(e.Location));
}
}
}
catch (Exception ex)
{
MessageDxUtil.ShowError(ex.Message);
}
}
【干货分享】一些基于DevExpress GridControl实现的界面处理功能(上)
七、直接新增保存的处理

在之前的文章中分别介绍了两种不同方式的数据直接在GridView列表中处理的方式,本质上两者是一致的,都是利用GridView本身的一些事件进行操作,实现更加方便的数据录入体验。

我们一般通过 InitNewRow 、ValidateRow 、CellValueChanged来处理数据的录入操作,如下详细操作的界面代码所示。

private void RegisterEvent()
{
var grd = this.gridControl1;
var grv = this.gridView1;
grv.InitGridView(GridType.NewItem, false, EditorShowMode.MouseDownFocused, "");
//创建显示的列
grv.CreateColumn("ItemNo", "备件编号", 120).CreateButtonEdit().ButtonClick += (s, e) =>
{
#region 选取备件信息,返回后赋值当前记录
if (grv.GetFocusedRow() == null)
{
grv.AddNewRow();//一定要增加
}
FrmSelectItemDetail dlg = new FrmSelectItemDetail();
dlg.WareHouse = this.txtWareHouse.Text;
if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
var info = dlg.ItemDetailInfo;
if (info != null)
{
grv.SetFocusedRowCellValue("ItemNo", info.ItemNo);
grv.SetFocusedRowCellValue("ItemName", info.ItemName);
grv.SetFocusedRowCellValue("ItemBigType", info.ItemBigType);
grv.SetFocusedRowCellValue("ItemType", info.ItemType);
grv.SetFocusedRowCellValue("MapNo", info.MapNo);
grv.SetFocusedRowCellValue("Specification", info.Specification);
grv.SetFocusedRowCellValue("Unit", info.Unit);
grv.SetFocusedRowCellValue("Price", info.Price);
grv.SetFocusedRowCellValue("Material", info.Material);
grv.SetFocusedRowCellValue("Source", info.Source);
grv.SetFocusedRowCellValue("StoragePos", info.StoragePos);
grv.SetFocusedRowCellValue("UsagePos", info.UsagePos);
grv.SetFocusedRowCellValue("WareHouse", info.WareHouse);
grv.SetFocusedRowCellValue("Dept", info.Dept);
grv.SetFocusedRowCellValue("Quantity", 1);//默认数量为1
}
}
#endregion
};
grv.CreateColumn("ItemName", "备件名称", 120);
grv.CreateColumn("Quantity", "数量").CreateSpinEdit();
grv.CreateColumn("ItemBigType", "备件属类", 120);
grv.CreateColumn("ItemType", "备件类别", 120);
grv.CreateColumn("MapNo", "图号");
grv.CreateColumn("Specification", "规格型号", 120);
grv.CreateColumn("Unit", "单位");
grv.CreateColumn("Price", "单价");
grv.CreateColumn("Amount", "金额");
grv.CreateColumn("Material", "材质", 120);
grv.CreateColumn("Source", "来源", 120);
grv.CreateColumn("StoragePos", "库位", 120);
grv.CreateColumn("UsagePos", "使用位置", 120);
grv.CreateColumn("WareHouse", "所属库房", 120);
grv.CreateColumn("Dept", "所属部门", 120);

//设置部分字段不可修改
var readonlyFields = "ItemName,ItemBigType,ItemType,MapNo,Specification,Unit,Price,Amount,Material,Source,UsagePos,WareHouse,Dept";
grv.SetColumnsReadOnly(readonlyFields);

//绑定数据源,否则无法新增存储
var list = new List<ItemDetailInfo>();
var dt = DataTableHelper.ConvertToDataTable<ItemDetailInfo>(list);

//同时增加两列在实体类属性里没有的列
dt.Columns.Add(new DataColumn("Quantity", typeof(int)));
dt.Columns.Add(new DataColumn("Amount", typeof(decimal)));
grd.DataSource = dt;

grv.InitNewRow += delegate(object sender, InitNewRowEventArgs e)
{
//如果是GUID的主键,可以初始化,以及赋值明细记录的父ID等操作
//GridView gridView = grd.FocusedView as GridView;
//gridView.SetFocusedRowCellValue("ID", Guid.NewGuid().ToString());
};
grv.ValidateRow += delegate(object sender, ValidateRowEventArgs e)
{
//校验一些不能为空的字段
var result = grd.ValidateRowNull(e, new string[]
{
"ItemNo",
"ItemName",
"Quantity"
});
};
grv.CellValueChanged += (object sender, CellValueChangedEventArgs e) =>
{
//根据数量计算金额
if (e.Column.FieldName == "Quantity" && e.Value != null)
{
var Price = string.Concat(grv.GetFocusedRowCellValue("Price")).ToDecimal();
var Quantity = string.Concat(e.Value).ToDecimal();
grv.SetFocusedRowCellValue("Amount", Price * Quantity);
}
};
grv.RowCellStyle += (object sender, RowCellStyleEventArgs e) =>
{
//设置特殊颜色标志
if (e.Column.FieldName == "Quantity" )
{
e.Appearance.BackColor = Color.Moccasin;
e.Appearance.ForeColor = Color.Red;
}
};
}

而如果需要结合删除的功能,那么可以增加对RowDeleted的事件处理。

//行删除操作
grv.OptionsBehavior.AllowDeleteRows = DefaultBoolean.True;
grv.RowDeleted += (s, ee) =>
{
//同时移除价格列表
var info = ee.Row as OrderInfo;
if(info != null)
{
this.OrderInfos.Remove(info);
for (int i = 0; i < this.gridView2.RowCount; i++)
{
var code = (string)this.gridView2.GetRowCellValue(i, "产品编码");
if(info.产品编码 == code)
{
this.gridView2.DeleteRow(i);
}
}
}
};
grv.KeyDown += (s, ee) =>
{
if (ee.KeyCode == Keys.Delete)
{
gridView1.DeleteSelectedRows();
ee.Handled = true;
}
};

以上就是在实际项目中,常用到的GridControl和GridView的常规处理方法,用好这些控件的处理,可以极大程度的提高用户的界面体验。


更多DevExpress线上公开课、中文教程资讯请上中文网获取

DevExpress公开课火热报名中
本站文章除注明转载外,均为本站原创或翻译
欢迎任何形式的转载,但请务必注明出处,尊重他人劳动成果
转载请注明:文章转载自:DevExpress控件中文网 [https://www.devexpresscn.com/]
本文地址:https://www.devexpresscn.com/post/3825.html

相关产品: DevExpress Universal Subscription,

扫码咨询
电话咨询
023-68661681
返回
顶部