翼度科技»论坛 编程开发 .net 查看内容

在DevExpress中使用BandedGridView表格实现多行表头的处理

4

主题

4

帖子

12

积分

新手上路

Rank: 1

积分
12
在之前较早随笔中介绍过实现多行表头的处理,通过手工创建字段以及映射数据源字段属性的方式实现,有些客户反映是否可以通过代码方式更方便的创建对应的处理操作,因此本篇随笔继续探讨这个多行表头的处理的操作,使用代码的方式结合扩展函数处理,快速的实现GridControl的多行表头的处理操作。
1、回顾使用手工创建BandedColumn和绑定字段列

在随笔《DevExpress控件开发常用要点(项目总结版)》总结了一些GridControl控件的一些操作,其中也提到了多行表头绑定处理,如下界面所示。

有时候,我们为了一些特殊的需要,要对表头进行特别的排版,使其支持多行表头的效果,如上图所示,这样方便对各项内容进行归类显示,易于阅读,在DevExpress中应该如何实现这个效果呢?
1)先在设计模式将普通的GridView转换为BandedGridView或者AdvBandedGridView,这样才能支持这种多行表头的做法,如下所示。

2)定义一些字段,用来显示其中的内容,如下图所示。

3)定义一些Band列,设置相关的属性,并把设计界面中的字段列表拖动到对应过的Band列上面,这样就构成了一个Band列和字段内容的对应关系。

完成上面的绑定关系后,记得设置GridView控件的属性,使其不要显示原本的ColumnHeader等内容。

设置好这些内容,才能合理、完美显示出多行表头的信息。
 
2、使用代码的方式结合扩展函数处理,快速的实现GridControl的多行表头

上面的操作,适合于新手的一些简单的字段绑定处理,有时候我们为了方便,可能更倾向于使用代码的方式快速构建多行表头的操作。
我们通过查看代码,可以了解GridBand对象是一个嵌套的关系,它类似树形结构,可以有很多层的子集合,也就是嵌套的头部条,它结合字段列对象GridColumn就形成了BandedGridColumn的信息。
我们需要知道GridBand只是一个头部的条状列信息,一般用来覆盖GridColumn的默认列头信息,因此需要设置一定的样式来禁用显示默认的GridColumn的头部信息。
  1. view.OptionsView.ShowColumnHeaders = false; //因为有Band列了,所以把ColumnHeader隐藏
复制代码
因此我们创建一个扩展的静态类文件,并加入设置BandedGridView样式的处理扩展方法,把相关的样式统一处理,如下所示。
  1.     /// <summary>
  2.     /// GridView及其RepositoryItem编辑控件的扩展类
  3.     /// </summary>
  4.     public static class Grid_Extension
  5.     {
  6.         /// <summary>
  7.         /// 设置BandedGridView的样式
  8.         /// </summary>
  9.         /// <param name="view"></param>
  10.         public static void SetBandedViewStyle(this BandedGridView view)
  11.         {
  12.             view.BeginUpdate(); //开始视图的编辑,防止触发其他事件
  13.             view.Bands.Clear();
  14.             //修改附加选项
  15.             view.OptionsView.ShowColumnHeaders = false; //因为有Band列了,所以把ColumnHeader隐藏
  16.             view.OptionsView.ShowGroupPanel = false;    //如果没必要分组,就把它去掉
  17.             view.OptionsView.EnableAppearanceEvenRow = false; //是否启用偶数行外观
  18.             view.OptionsView.EnableAppearanceOddRow = true;   //是否启用奇数行外观
  19.             view.OptionsView.ShowFilterPanelMode = ShowFilterPanelMode.Never;   //是否显示过滤面板
  20.             view.OptionsCustomization.AllowColumnMoving = false;                //是否允许移动列
  21.             view.OptionsCustomization.AllowColumnResizing = false;              //是否允许调整列宽
  22.             view.OptionsCustomization.AllowGroup = false;                       //是否允许分组
  23.             view.OptionsCustomization.AllowFilter = false;                      //是否允许过滤
  24.             view.OptionsCustomization.AllowSort = true;                         //是否允许排序
  25.             view.OptionsSelection.EnableAppearanceFocusedCell = true;           //是否焦点显示选中的单元格           
  26.             view.EndUpdate();   //结束视图的编辑
  27.         }
复制代码
由于GridBand可能是嵌套的多层表头,因此为了方便,可以单独设置一个扩展方法创建GridBand,这样有助于引用对象。
  1.         /// <summary>
  2.         /// 创建绑定Banded列
  3.         /// </summary>
  4.         /// <param name="view"></param>
  5.         /// <param name="caption"></param>
  6.         /// <param name="width"></param>
  7.         /// <param name="fixedStyle"></param>
  8.         /// <param name="visible">是否可见</param>
  9.         /// <returns></returns>
  10.         public static GridBand CreateBand(this BandedGridView view, string caption, int width = 80, FixedStyle fixedStyle = FixedStyle.None, bool visible = true)
  11.         {
  12.             //使用多语言处理标题
  13.             caption = JsonLanguage.Default.GetString(caption);
  14.             var band = new GridBand
  15.             {
  16.                 Caption = caption,
  17.                 Width = width,
  18.                 Fixed = fixedStyle,
  19.                 Visible = visible,  
  20.             };
  21.             view.Bands.Add(band);
  22.             band.VisibleIndex = view.Bands.Count;
  23.             band.AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center;
  24.             return band;
  25.         }
复制代码
这样我们就可以传递GridBand对象来构建多层级的字段列信息了,利用扩展函数,我们可以方便的实现创建绑定列信息。
  1.         /// <summary>
  2.         /// 根据指定的GridBand父级对象,构建BandedGridColumn列对象
  3.         /// </summary>
  4.         /// <param name="view"></param>
  5.         /// <param name="band"></param>
  6.         /// <param name="fieldName"></param>
  7.         /// <param name="caption"></param>
  8.         /// <param name="allowEdit"></param>
  9.         /// <param name="allowMerge"></param>
  10.         /// <returns></returns>
  11.         public static BandedGridColumn CreateBandColumn(this BandedGridView view, GridBand band, string fieldName, string caption, bool allowEdit = true, DefaultBoolean allowMerge = DefaultBoolean.False)
  12.         {
  13.             //使用多语言处理标题
  14.             caption = JsonLanguage.Default.GetString(caption);
  15.             var gridColumn = new BandedGridColumn()
  16.             {
  17.                 FieldName = fieldName,
  18.                 Caption = caption,
  19.                 UnboundType = UnboundColumnType.Bound,
  20.                 Visible = true
  21.             };
  22.             band.AppearanceHeader.BackColor  = Color.LightGreen;
  23.             var newBand = band.Children.AddBand(caption);
  24.             newBand.AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center; //文本居中
  25.             newBand.Columns.Add(gridColumn);
  26.             gridColumn.AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center;
  27.             gridColumn.AppearanceCell.TextOptions.VAlignment = VertAlignment.Center;
  28.             gridColumn.OptionsColumn.AllowEdit = allowEdit;
  29.             if (!allowEdit)
  30.             {
  31.                 gridColumn.AppearanceHeader.ForeColor = Color.Gray;
  32.             }
  33.             bool allowCellMerge = !view.OptionsView.AllowCellMerge && allowMerge == DefaultBoolean.True;
  34.             if (allowCellMerge)
  35.             {
  36.                 view.OptionsView.AllowCellMerge = true;
  37.             }
  38.             gridColumn.OptionsColumn.AllowMerge = allowMerge;
  39.             return gridColumn;
  40.         }
复制代码
而如果一般的列,没有多层嵌套的GridBand,也就是只有一层的表头,我们也需要根据字段信息进行构建一个GridBandColumn来显示信息,如下所示。
  1.         /// <summary>
  2.         /// 根据字段信息,构建BandedGridColumn列对象
  3.         /// </summary>
  4.         /// <param name="view">视图对象</param>
  5.         /// <param name="fieldName">字段名称</param>
  6.         /// <param name="caption">显示名称</param>
  7.         /// <param name="width">列宽度</param>
  8.         /// <param name="fixedStyle">固定显示模式</param>
  9.         /// <param name="visible">是否可见</param>
  10.         /// <param name="allowEdit">是否可编辑</param>
  11.         /// <param name="allowMerge">是否可合并</param>
  12.         /// <param name="unboundColumnType">绑定类型,默认为UnboundColumnType.Bound</param>
  13.         /// <returns></returns>
  14.         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)
  15.         {
  16.             //使用多语言处理标题
  17.             caption = JsonLanguage.Default.GetString(caption);
  18.             var gridColumn = new BandedGridColumn()
  19.             {
  20.                 FieldName = fieldName,
  21.                 Caption = caption,
  22.                 Width = width,
  23.                 UnboundType = unboundColumnType,
  24.             };
  25.             var band = view.CreateBand(caption, width, fixedStyle);
  26.             band.Visible = visible;
  27.             band.Columns.Add(gridColumn);
  28.             //view.Columns[fieldName].OwnerBand = band;
  29.             gridColumn.AbsoluteIndex = view.Columns.Count;
  30.             gridColumn.Visible = visible;//是否可见
  31.             if (visible)
  32.             {
  33.                 gridColumn.VisibleIndex = view.Columns.Count;
  34.             }
  35.             gridColumn.AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center;
  36.             gridColumn.AppearanceCell.TextOptions.VAlignment = VertAlignment.Center;
  37.             gridColumn.OptionsColumn.AllowEdit = allowEdit;
  38.             if (!allowEdit)
  39.             {
  40.                 gridColumn.AppearanceHeader.ForeColor = Color.Gray;
  41.             }
  42.             bool allowCellMerge = !view.OptionsView.AllowCellMerge && allowMerge == DefaultBoolean.True;
  43.             if (allowCellMerge)
  44.             {
  45.                 view.OptionsView.AllowCellMerge = true;
  46.             }
  47.             gridColumn.OptionsColumn.AllowMerge = allowMerge;
  48.             gridColumn.Fixed = fixedStyle;
  49.             return gridColumn;
  50.         }
复制代码
有了这些扩展函数的铺垫,我们在实际界面中展示多层级的多行表头就会变得很容易了。为了方便介绍,我创建一个简单的窗体用来展示多行表头的代码绑定处理。
创建一个默认的窗体,放置GridControl,并把默认的GridView视图,转换为BandedGridView视图对象,如下所示。

为了绑定一些字段信息供显示、编辑处理,我们创建了一个表格,包含信息:Id,姓名,外科皮肤科_诊断,外科皮肤科_结论,神经精神科_诊断,神经精神科_结论,内科_诊断,内科_结论,眼科_诊断,眼科_结论,检查时间,备注 等字段内容,如下代码所示。
  1.             var table = DataTableHelper.CreateTable("Id|int,姓名,外科皮肤科_诊断,外科皮肤科_结论,神经精神科_诊断,神经精神科_结论,内科_诊断,内科_结论,眼科_诊断,眼科_结论,检查时间,备注");
  2.             
  3.             //准备飞行员体检测试数据
  4.             for (int i =1; i <= 50;i++)
  5.             {
  6.                 var dr = table.NewRow();
  7.                 dr["Id"] = i;
  8.                 dr["姓名"] = $"某某{i}";
  9.                 dr["外科皮肤科_诊断"] = "健康";
  10.                 dr["外科皮肤科_结论"] = "合格";
  11.                 dr["神经精神科_诊断"] = "健康";
  12.                 dr["神经精神科_结论"] = "合格";
  13.                 dr["内科_诊断"] = "健康";
  14.                 dr["内科_结论"] = "合格";
  15.                 dr["眼科_诊断"] = "健康";
  16.                 dr["眼科_结论"] = "合格";
  17.                 dr["检查时间"] = DateTime.Now;
  18.                 dr["备注"] = "";
  19.                 table.Rows.Add(dr);
  20.             }
复制代码
初始化BandedGridView信息后,如需绑定数据,那么还需要对GridControl的数据源进行绑定才能进行编辑或者显示,如下所示的代码操作。
[code]/// /// 绑定数据列表/// private void BindData(){    var table = DataTableHelper.CreateTable("Id|int,姓名,外科皮肤科_诊断,外科皮肤科_结论,神经精神科_诊断,神经精神科_结论,内科_诊断,内科_结论,眼科_诊断,眼科_结论,检查时间,备注");        //准备飞行员体检测试数据    for (int i =1; i

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具