- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
在之前较早随笔中介绍过实现多行表头的处理,通过手工创建字段以及映射数据源字段属性的方式实现,有些客户反映是否可以通过代码方式更方便的创建对应的处理操作,因此本篇随笔继续探讨这个多行表头的处理的操作,使用代码的方式结合扩展函数处理,快速的实现GridControl的多行表头的处理操作.
在随笔《 DevExpress控件开发常用要点(项目总结版) 》总结了一些GridControl控件的一些操作,其中也提到了多行表头绑定处理,如下界面所示.
有时候,我们为了一些特殊的需要,要对表头进行特别的排版,使其支持多行表头的效果,如上图所示,这样方便对各项内容进行归类显示,易于阅读,在DevExpress中应该如何实现这个效果呢?
1)先在设计模式将普通的GridView转换为BandedGridView或者AdvBandedGridView,这样才能支持这种多行表头的做法,如下所示.
2)定义一些字段,用来显示其中的内容,如下图所示.
3)定义一些Band列,设置相关的属性,并把设计界面中的字段列表拖动到对应过的Band列上面,这样就构成了一个Band列和字段内容的对应关系.
完成上面的绑定关系后,记得设置GridView控件的属性,使其不要显示原本的ColumnHeader等内容.
设置好这些内容,才能合理、完美显示出多行表头的信息.
。
上面的操作,适合于新手的一些简单的字段绑定处理,有时候我们为了方便,可能更倾向于使用代码的方式快速构建多行表头的操作.
我们通过查看代码,可以了解GridBand对象是一个嵌套的关系,它类似树形结构,可以有很多层的子集合,也就是嵌套的头部条,它结合字段列对象GridColumn就形成了BandedGridColumn的信息.
我们需要知道GridBand只是一个头部的条状列信息,一般用来覆盖GridColumn的默认列头信息,因此需要设置一定的样式来禁用显示默认的GridColumn的头部信息.
view.OptionsView.ShowColumnHeaders = false ; // 因为有Band列了,所以把ColumnHeader隐藏
因此我们创建一个扩展的静态类文件,并加入设置BandedGridView样式的处理扩展方法,把相关的样式统一处理,如下所示.
/// <summary> /// GridView及其RepositoryItem编辑控件的扩展类 /// </summary> public static class Grid_Extension { /// <summary> /// 设置BandedGridView的样式 /// </summary> /// <param name="view"></param> public static void SetBandedViewStyle( this BandedGridView view) { view.BeginUpdate(); // 开始视图的编辑,防止触发其他事件 view.Bands.Clear(); // 修改附加选项 view.OptionsView.ShowColumnHeaders = false ; // 因为有Band列了,所以把ColumnHeader隐藏 view.OptionsView.ShowGroupPanel = false ; // 如果没必要分组,就把它去掉 view.OptionsView.EnableAppearanceEvenRow = false ; // 是否启用偶数行外观 view.OptionsView.EnableAppearanceOddRow = true ; // 是否启用奇数行外观 view.OptionsView.ShowFilterPanelMode = ShowFilterPanelMode.Never; // 是否显示过滤面板 view.OptionsCustomization.AllowColumnMoving = false ; // 是否允许移动列 view.OptionsCustomization.AllowColumnResizing = false ; // 是否允许调整列宽 view.OptionsCustomization.AllowGroup = false ; // 是否允许分组 view.OptionsCustomization.AllowFilter = false ; // 是否允许过滤 view.OptionsCustomization.AllowSort = true ; // 是否允许排序 view.OptionsSelection.EnableAppearanceFocusedCell = true ; // 是否焦点显示选中的单元格 view.EndUpdate(); // 结束视图的编辑 }
由于GridBand可能是嵌套的多层表头,因此为了方便,可以单独设置一个扩展方法创建GridBand,这样有助于引用对象.
/// <summary> /// 创建绑定Banded列 /// </summary> /// <param name="view"></param> /// <param name="caption"></param> /// <param name="width"></param> /// <param name="fixedStyle"></param> /// <param name="visible"> 是否可见 </param> /// <returns></returns> public static GridBand CreateBand( this BandedGridView view, string caption, int width = 80 , FixedStyle fixedStyle = FixedStyle.None, bool visible = true ) { // 使用多语言处理标题 caption = JsonLanguage.Default.GetString(caption); var band = new GridBand { Caption = caption, Width = width, Fixed = fixedStyle, Visible = visible, }; view.Bands.Add(band); band.VisibleIndex = view.Bands.Count; band.AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center; return band; }
这样我们就可以传递GridBand对象来构建多层级的字段列信息了,利用扩展函数,我们可以方便的实现创建绑定列信息.
/// <summary> /// 根据指定的GridBand父级对象,构建BandedGridColumn列对象 /// </summary> /// <param name="view"></param> /// <param name="band"></param> /// <param name="fieldName"></param> /// <param name="caption"></param> /// <param name="allowEdit"></param> /// <param name="allowMerge"></param> /// <returns></returns> public static BandedGridColumn CreateBandColumn( this BandedGridView view, GridBand band, string fieldName, string caption, bool allowEdit = true , DefaultBoolean allowMerge = DefaultBoolean.False) { // 使用多语言处理标题 caption = JsonLanguage.Default.GetString(caption); var gridColumn = new BandedGridColumn() { FieldName = fieldName, Caption = caption, UnboundType = UnboundColumnType.Bound, Visible = true }; band.AppearanceHeader.BackColor = Color.LightGreen; var newBand = band.Children.AddBand(caption); newBand.AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center; // 文本居中 newBand.Columns.Add(gridColumn); gridColumn.AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center; gridColumn.AppearanceCell.TextOptions.VAlignment = VertAlignment.Center; gridColumn.OptionsColumn.AllowEdit = allowEdit; if (! allowEdit) { gridColumn.AppearanceHeader.ForeColor = Color.Gray; } bool allowCellMerge = !view.OptionsView.AllowCellMerge && allowMerge == DefaultBoolean.True; if (allowCellMerge) { view.OptionsView.AllowCellMerge = true ; } gridColumn.OptionsColumn.AllowMerge = allowMerge; return gridColumn; }
而如果一般的列,没有多层嵌套的GridBand,也就是只有一层的表头,我们也需要根据字段信息进行构建一个GridBandColumn来显示信息,如下所示.
/// <summary> /// 根据字段信息,构建BandedGridColumn列对象 /// </summary> /// <param name="view"> 视图对象 </param> /// <param name="fieldName"> 字段名称 </param> /// <param name="caption"> 显示名称 </param> /// <param name="width"> 列宽度 </param> /// <param name="fixedStyle"> 固定显示模式 </param> /// <param name="visible"> 是否可见 </param> /// <param name="allowEdit"> 是否可编辑 </param> /// <param name="allowMerge"> 是否可合并 </param> /// <param name="unboundColumnType"> 绑定类型,默认为UnboundColumnType.Bound </param> /// <returns></returns> public static BandedGridColumn CreateBandColumn( this BandedGridView view, string fieldName, string caption, int width = 80 , FixedStyle fixedStyle = FixedStyle.None, bool visible = true , bool allowEdit = true , DefaultBoolean allowMerge = DefaultBoolean.False, UnboundColumnType unboundColumnType = UnboundColumnType.Bound) { // 使用多语言处理标题 caption = JsonLanguage.Default.GetString(caption); var gridColumn = new BandedGridColumn() { FieldName = fieldName, Caption = caption, Width = width, UnboundType = unboundColumnType, }; var band = view.CreateBand(caption, width, fixedStyle); band.Visible = visible; band.Columns.Add(gridColumn); // view.Columns[fieldName].OwnerBand = band; gridColumn.AbsoluteIndex = view.Columns.Count; gridColumn.Visible = visible; // 是否可见 if (visible) { gridColumn.VisibleIndex = view.Columns.Count; } gridColumn.AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center; gridColumn.AppearanceCell.TextOptions.VAlignment = VertAlignment.Center; gridColumn.OptionsColumn.AllowEdit = allowEdit; if (! allowEdit) { gridColumn.AppearanceHeader.ForeColor = Color.Gray; } bool allowCellMerge = !view.OptionsView.AllowCellMerge && allowMerge == DefaultBoolean.True; if (allowCellMerge) { view.OptionsView.AllowCellMerge = true ; } gridColumn.OptionsColumn.AllowMerge = allowMerge; gridColumn.Fixed = fixedStyle; return gridColumn; }
有了这些扩展函数的铺垫,我们在实际界面中展示多层级的多行表头就会变得很容易了。为了方便介绍,我创建一个简单的窗体用来展示多行表头的代码绑定处理.
创建一个默认的窗体,放置GridControl,并把默认的GridView视图,转换为BandedGridView视图对象,如下所示.
为了绑定一些字段信息供显示、编辑处理,我们创建了一个表格,包含信息: Id,姓名,外科皮肤科_诊断,外科皮肤科_结论,神经精神科_诊断,神经精神科_结论,内科_诊断,内科_结论,眼科_诊断,眼科_结论,检查时间,备注 等字段内容,如下代码所示.
var table = DataTableHelper.CreateTable( " Id|int,姓名,外科皮肤科_诊断,外科皮肤科_结论,神经精神科_诊断,神经精神科_结论,内科_诊断,内科_结论,眼科_诊断,眼科_结论,检查时间,备注 " ); // 准备飞行员体检测试数据 for ( int i = 1 ; i <= 50 ;i++ ) { var dr = table.NewRow(); dr[ " Id " ] = i; dr[ " 姓名 " ] = $ " 某某{i} " ; dr[ " 外科皮肤科_诊断 " ] = " 健康 " ; dr[ " 外科皮肤科_结论 " ] = " 合格 " ; dr[ " 神经精神科_诊断 " ] = " 健康 " ; dr[ " 神经精神科_结论 " ] = " 合格 " ; dr[ " 内科_诊断 " ] = " 健康 " ; dr[ " 内科_结论 " ] = " 合格 " ; dr[ " 眼科_诊断 " ] = " 健康 " ; dr[ " 眼科_结论 " ] = " 合格 " ; dr[ " 检查时间 " ] = DateTime.Now; dr[ " 备注 " ] = "" ; table.Rows.Add(dr); }
首先需要创建GridView的初始化信息,如绑定那些字段列,结合多表头的处理方式,如下代码所示.
/// <summary> /// 初始化列表 /// </summary> private void InitGridView() { var grid = this .gridControl1; var grv = this .gridControl1.MainView as BandedGridView; grid.ContextMenuStrip = this .contextMenuStrip1; // 右键菜单 // 初始化GridView样式,并设置相关的BandedGridView样式 grv.InitGridView(GridType.EditOnly, false , EditorShowMode.MouseDownFocused, "" ); grv.SetBandedViewStyle(); // 创建显示的列: // Id,姓名,外科皮肤科_诊断,外科皮肤科_结论,神经精神科_诊断,神经精神科_结论,内科_诊断,内科_结论,眼科_诊断,眼科_结论,检查时间,备注 grv.Columns.Clear(); grv.CreateBandColumn( " Id " , " Id " , 80 , FixedStyle.Left, true , false ); grv.CreateBandColumn( " 姓名 " , " 客户名称 " , 80 , FixedStyle.Left, true , false ); var band1 = grv.CreateBand( " 外科皮肤科 " , 120 ); grv.CreateBandColumn(band1, " 外科皮肤科_诊断 " , " 诊断 " ); grv.CreateBandColumn(band1, " 外科皮肤科_结论 " , " 结论 " ); var band2 = grv.CreateBand( " 神经精神科 " , 120 ); grv.CreateBandColumn(band2, " 神经精神科_诊断 " , " 诊断 " ); grv.CreateBandColumn(band2, " 神经精神科_结论 " , " 结论 " ); var band3 = grv.CreateBand( " 内科 " , 120 ); grv.CreateBandColumn(band3, " 内科_诊断 " , " 诊断 " ); grv.CreateBandColumn(band3, " 内科_结论 " , " 结论 " ); var band4 = grv.CreateBand( " 眼科 " , 120 ); grv.CreateBandColumn(band4, " 眼科_诊断 " , " 诊断 " ); grv.CreateBandColumn(band4, " 眼科_结论 " , " 结论 " ); var colCheckTime = grv.CreateBandColumn( " 检查时间 " , " 检查时间 " ).CreateDateEdit(); // 可修改 colCheckTime.EditMask = " yyyy-MM-dd " ; colCheckTime.DisplayFormat.FormatString = " yyyy-MM-dd " ; colCheckTime.EditFormat.FormatString = " yyyy-MM-dd " ; colCheckTime.CustomDisplayText += (s, e) => { if (e.Value != null && e.Value.ToString() != "" ) { if (Convert.ToDateTime(e.Value) <= Convert.ToDateTime( " 1900-1-1 " )) { e.DisplayText = "" ; } else { e.DisplayText = Convert.ToDateTime(e.Value).ToString( " yyyy-MM-dd " ); } } }; // 可修改 grv.CreateBandColumn( " 备注 " , " 备注 " , 200 ) ; // 设置部分字段不可修改 var editFields = " 外科皮肤科_诊断,外科皮肤科_结论,神经精神科_诊断,神经精神科_结论,内科_诊断,内科_结论,眼科_诊断,眼科_结论,检查时间,备注 " ; grv.SetColumnsReadOnly( " * " , false ); grv.SetColumnsReadOnly(editFields, true ); // 检查输入 grv.ValidateRow += (s, e) => { // 校验一些不能为空的字段 // var result = grid.ValidateRowNull(e, new string[] // { // "产品编码", // "产品名称" // }); }; // 值更改触发 grv.CellValueChanged += (s, 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 += (s, e) => { // 设置特殊颜色标志 if (editFields.Contains(e.Column.FieldName)) { e.Appearance.BackColor = Color.Azure; e.Appearance.ForeColor = Color.Blue; } }; }
初始化BandedGridView信息后,如需绑定数据,那么还需要对GridControl的数据源进行绑定才能进行编辑或者显示,如下所示的代码操作.
/// <summary> /// 绑定数据列表 /// </summary> private void BindData() { var table = DataTableHelper.CreateTable( " Id|int,姓名,外科皮肤科_诊断,外科皮肤科_结论,神经精神科_诊断,神经精神科_结论,内科_诊断,内科_结论,眼科_诊断,眼科_结论,检查时间,备注 " ); // 准备飞行员体检测试数据 for ( int i = 1 ; i <= 50 ;i++ ) { var dr = table.NewRow(); dr[ " Id " ] = i; dr[ " 姓名 " ] = $ " 某某{i} " ; dr[ " 外科皮肤科_诊断 " ] = " 健康 " ; dr[ " 外科皮肤科_结论 " ] = " 合格 " ; dr[ " 神经精神科_诊断 " ] = " 健康 " ; dr[ " 神经精神科_结论 " ] = " 合格 " ; dr[ " 内科_诊断 " ] = " 健康 " ; dr[ " 内科_结论 " ] = " 合格 " ; dr[ " 眼科_诊断 " ] = " 健康 " ; dr[ " 眼科_结论 " ] = " 合格 " ; dr[ " 检查时间 " ] = DateTime.Now; dr[ " 备注 " ] = "" ; table.Rows.Add(dr); } // 绑定数据源 var grv = this .bandedGridView1; grv.GridControl.DataSource = table; grv.RefreshData(); }
最后,我们把它放在开发框架(如有Winform界面部分的SqlSugar开发框架、Winform开发框架)的综合演示案例里面,供参考使用。界面效果如下所示.
对比手工的效果 。
实现功能差不多,通过代码方式,相对更加灵活一些.
以上就是综合介绍了手工处理和代码处理两种方式构建多行表头的处理操作,通过使用扩展函数方式,可以更快捷、更灵活的创建多表头的处理和数据的绑定展示,可以有效的减少我们在多表头上的操作摸索时间.
。
最后此篇关于在DevExpress中使用BandedGridView表格实现多行表头的处理的文章就讲到这里了,如果你想了解更多关于在DevExpress中使用BandedGridView表格实现多行表头的处理的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
背景: 我最近一直在使用 JPA,我为相当大的关系数据库项目生成持久层的轻松程度给我留下了深刻的印象。 我们公司使用大量非 SQL 数据库,特别是面向列的数据库。我对可能对这些数据库使用 JPA 有一
我已经在我的 maven pom 中添加了这些构建配置,因为我希望将 Apache Solr 依赖项与 Jar 捆绑在一起。否则我得到了 SolarServerException: ClassNotF
interface ITurtle { void Fight(); void EatPizza(); } interface ILeonardo : ITurtle {
我希望可用于 Java 的对象/关系映射 (ORM) 工具之一能够满足这些要求: 使用 JPA 或 native SQL 查询获取大量行并将其作为实体对象返回。 允许在行(实体)中进行迭代,并在对当前
好像没有,因为我有实现From for 的代码, 我可以转换 A到 B与 .into() , 但同样的事情不适用于 Vec .into()一个Vec . 要么我搞砸了阻止实现派生的事情,要么这不应该发
在 C# 中,如果 A 实现 IX 并且 B 继承自 A ,是否必然遵循 B 实现 IX?如果是,是因为 LSP 吗?之间有什么区别吗: 1. Interface IX; Class A : IX;
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在阅读标准haskell库的(^)的实现代码: (^) :: (Num a, Integral b) => a -> b -> a x0 ^ y0 | y0 a -> b ->a expo x0
我将把国际象棋游戏表示为 C++ 结构。我认为,最好的选择是树结构(因为在每个深度我们都有几个可能的移动)。 这是一个好的方法吗? struct TreeElement{ SomeMoveType
我正在为用户名数据库实现字符串匹配算法。我的方法采用现有的用户名数据库和用户想要的新用户名,然后检查用户名是否已被占用。如果采用该方法,则该方法应该返回带有数据库中未采用的数字的用户名。 例子: “贾
我正在尝试实现 Breadth-first search algorithm , 为了找到两个顶点之间的最短距离。我开发了一个 Queue 对象来保存和检索对象,并且我有一个二维数组来保存两个给定顶点
我目前正在 ika 中开发我的 Python 游戏,它使用 python 2.5 我决定为 AI 使用 A* 寻路。然而,我发现它对我的需要来说太慢了(3-4 个敌人可能会落后于游戏,但我想供应 4-
我正在寻找 Kademlia 的开源实现C/C++ 中的分布式哈希表。它必须是轻量级和跨平台的(win/linux/mac)。 它必须能够将信息发布到 DHT 并检索它。 最佳答案 OpenDHT是
我在一本书中读到这一行:-“当我们要求 C++ 实现运行程序时,它会通过调用此函数来实现。” 而且我想知道“C++ 实现”是什么意思或具体是什么。帮忙!? 最佳答案 “C++ 实现”是指编译器加上链接
我正在尝试使用分支定界的 C++ 实现这个背包问题。此网站上有一个 Java 版本:Implementing branch and bound for knapsack 我试图让我的 C++ 版本打印
在很多情况下,我需要在 C# 中访问合适的哈希算法,从重写 GetHashCode 到对数据执行快速比较/查找。 我发现 FNV 哈希是一种非常简单/好/快速的哈希算法。但是,我从未见过 C# 实现的
目录 LRU缓存替换策略 核心思想 不适用场景 算法基本实现 算法优化
1. 绪论 在前面文章中提到 空间直角坐标系相互转换 ,测绘坐标转换时,一般涉及到的情况是:两个直角坐标系的小角度转换。这个就是我们经常在测绘数据处理中,WGS-84坐标系、54北京坐标系
在软件开发过程中,有时候我们需要定时地检查数据库中的数据,并在发现新增数据时触发一个动作。为了实现这个需求,我们在 .Net 7 下进行一次简单的演示. PeriodicTimer .
二分查找 二分查找算法,说白了就是在有序的数组里面给予一个存在数组里面的值key,然后将其先和数组中间的比较,如果key大于中间值,进行下一次mid后面的比较,直到找到相等的,就可以得到它的位置。
我是一名优秀的程序员,十分优秀!