最近cs项目中有个看板的功能需求,整个系统是基于DevExpress组件开发的,由于对这个组件的布局不是很熟,也借鉴了网上一些其他人的做法,普遍都是通过GridControl的BandedGridView来实现的,但是网上很多做法都是从设计视图手动创建绑定Brand的,并不是动态生成的,于是我花了半天时间,把这个控件的用法研究了一下,可以通过代码动态创建生成表头,写了个demo,在这和大家分享一下。

GridControl里面默认的控件是GridView,需要手动转换成BrandedGridView,具体如何转换,网上有很多,这里就不详细介绍了。

先看下designer的代码:

  1. namespace WindowsFormsApplication1
  2. {
  3. partial class Form2
  4. {
  5. /// <summary>
  6. /// Required designer variable.
  7. /// </summary>
  8. private System.ComponentModel.IContainer components = null;
  9.  
  10. /// <summary>
  11. /// Clean up any resources being used.
  12. /// </summary>
  13. /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
  14. protected override void Dispose(bool disposing)
  15. {
  16. if (disposing && (components != null))
  17. {
  18. components.Dispose();
  19. }
  20. base.Dispose(disposing);
  21. }
  22.  
  23. #region Windows Form Designer generated code
  24.  
  25. /// <summary>
  26. /// Required method for Designer support - do not modify
  27. /// the contents of this method with the code editor.
  28. /// </summary>
  29. private void InitializeComponent()
  30. {
  31. this.panel1 = new System.Windows.Forms.Panel();
  32. this.button1 = new System.Windows.Forms.Button();
  33. this.gridControl1 = new DevExpress.XtraGrid.GridControl();
  34. this.bandedGridView1 = new DevExpress.XtraGrid.Views.BandedGrid.BandedGridView();
  35. this.panel1.SuspendLayout();
  36. ((System.ComponentModel.ISupportInitialize)(this.gridControl1)).BeginInit();
  37. ((System.ComponentModel.ISupportInitialize)(this.bandedGridView1)).BeginInit();
  38. this.SuspendLayout();
  39. //
  40. // panel1
  41. //
  42. this.panel1.Controls.Add(this.button1);
  43. this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
  44. , );
  45. this.panel1.Name = "panel1";
  46. , );
  47. ;
  48. //
  49. // button1
  50. //
  51. , );
  52. this.button1.Name = "button1";
  53. , );
  54. ;
  55. this.button1.Text = "演示";
  56. this.button1.UseVisualStyleBackColor = true;
  57. this.button1.Click += new System.EventHandler(this.button1_Click);
  58. //
  59. // gridControl1
  60. //
  61. this.gridControl1.Dock = System.Windows.Forms.DockStyle.Fill;
  62. , );
  63. this.gridControl1.MainView = this.bandedGridView1;
  64. this.gridControl1.Name = "gridControl1";
  65. , );
  66. ;
  67. this.gridControl1.ViewCollection.AddRange(new DevExpress.XtraGrid.Views.Base.BaseView[] {
  68. this.bandedGridView1});
  69. //
  70. // bandedGridView1
  71. //
  72. this.bandedGridView1.GridControl = this.gridControl1;
  73. this.bandedGridView1.Name = "bandedGridView1";
  74. this.bandedGridView1.OptionsView.ShowGroupPanel = false;
  75. this.bandedGridView1.OptionsView.ShowIndicator = false;
  76. this.bandedGridView1.CustomDrawCell += BandedGridView1_CustomDrawCell;
  77. //
  78. // Form2
  79. //
  80. this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
  81. this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
  82. , );
  83. this.Controls.Add(this.gridControl1);
  84. this.Controls.Add(this.panel1);
  85. this.Name = "Form2";
  86. this.Text = "Form2";
  87. this.panel1.ResumeLayout(false);
  88. ((System.ComponentModel.ISupportInitialize)(this.gridControl1)).EndInit();
  89. ((System.ComponentModel.ISupportInitialize)(this.bandedGridView1)).EndInit();
  90. this.ResumeLayout(false);
  91.  
  92. }
  93.  
  94. #endregion
  95.  
  96. private System.Windows.Forms.Panel panel1;
  97. private System.Windows.Forms.Button button1;
  98. private DevExpress.XtraGrid.GridControl gridControl1;
  99. private DevExpress.XtraGrid.Views.BandedGrid.BandedGridView bandedGridView1;
  100. }
  101. }

然后是界面的代码:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.Drawing;
  5. using System.Windows.Forms;
  6. using DevExpress.Utils;
  7. using DevExpress.XtraGrid.Views.BandedGrid;
  8. using DevExpress.XtraGrid.Views.Base;
  9.  
  10. namespace WindowsFormsApplication1
  11. {
  12.  
  13. public partial class Form2 : Form
  14. {
  15. public Form2()
  16. {
  17. InitializeComponent();
  18. InitBandGrid();
  19. }
  20.  
  21. private void button1_Click(object sender, EventArgs e)
  22. {
  23. gridControl1.DataSource = GetData();
  24. }
  25.  
  26. List<ColumnHeaderInfo> InitColumnHeader()
  27. {
  28. string[] Day = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
  29. List<ColumnHeaderInfo> list = new List<ColumnHeaderInfo>();
  30. var date = DateTime.Now.Date;
  31. ; i < ; i++)
  32. {
  33. var colDate = date.AddDays(i);
  34. ColumnHeaderInfo info = new ColumnHeaderInfo
  35. {
  36. Date = colDate.ToString("yyyy-MM-dd"),
  37. WeekDay = Day[Convert.ToInt32(colDate.DayOfWeek.ToString("d"))]
  38. };
  39. list.Add(info);
  40. }
  41. return list;
  42. }
  43.  
  44. /// <summary>
  45. /// 根据仓库权限初始化仓库显示列头
  46. /// </summary>
  47. private void InitBandGrid()
  48. {
  49. var list = InitColumnHeader();
  50. bandedGridView1.BeginUpdate();
  51. bandedGridView1.BeginDataUpdate();
  52.  
  53. bandedGridView1.BandPanelRowHeight = ;
  54. bandedGridView1.RowHeight = ;
  55. bandedGridView1.OptionsView.ShowColumnHeaders = false; //因为有Band列了,所以把ColumnHeader隐藏
  56. bandedGridView1.OptionsView.AllowCellMerge = true;
  57.  
  58. bandedGridView1.Bands.Clear();
  59.  
  60. GridBand gbStoreType = new GridBand
  61. {
  62. Name = @"StoreType",
  63. Caption = @" "
  64. };
  65. BandedGridColumn col = new BandedGridColumn
  66. {
  67. Name = "colStoreType",
  68. Caption = @" ",
  69. FieldName = "StoreType",
  70. Visible = true
  71. };
  72. gbStoreType.Columns.Add(col); //把新增的显示字段绑定到gridband上,以供显示数据用
  73. bandedGridView1.Bands.Add(gbStoreType);
  74.  
  75. gbStoreType.View.Columns.Add(col);
  76.  
  77. if (list != null)
  78. foreach (var item in list)
  79. {
  80. GridBand gbDate = new GridBand
  81. {
  82. Name = @"Date_" + item.Date,
  83. Caption = item.Date
  84. };
  85. GridBand gbWeekDay = gbDate.Children.AddBand(item.WeekDay);
  86.  
  87. GridBand gbCol1 = gbWeekDay.Children.AddBand("预约收货时段");
  88.  
  89. //必须先将其绑定至bandgridview上后才能去添加column,否则无法加载数据
  90. var bandName1 = "Date_WeekDay_col1_" + item.Date;
  91. var bandFieldName1 = "Date_WeekDay_col1_" + item.Date;
  92. BandedGridColumn col1 = new BandedGridColumn
  93. {
  94. Name = bandName1,
  95. Caption = @"预约收货时段",
  96. FieldName = bandFieldName1,
  97. Visible = true
  98. };
  99. gbCol1.Columns.Add(col1); //把新增的显示字段绑定到gridband上,以供显示数据用
  100.  
  101. GridBand gbCol2 = gbWeekDay.Children.AddBand("实际预约/最大预约");
  102. var bandName2 = "Date_WeekDay_col2_" + item.Date;
  103. var bandFieldName2 = "Date_WeekDay_col2_" + item.Date;
  104. BandedGridColumn col2 = new BandedGridColumn
  105. {
  106. Name = bandName2,
  107. Caption = @"实际预约/最大预约",
  108. FieldName = bandFieldName2,
  109. Visible = true
  110. };
  111. gbCol2.Columns.Add(col2); //把新增的显示字段绑定到gridband上,以供显示数据用
  112.  
  113. bandedGridView1.Bands.Add(gbDate);
  114. gbCol1.View.Columns.Add(col1);
  115. gbCol2.View.Columns.Add(col2);
  116.  
  117. col1.OptionsColumn.AllowMerge = DefaultBoolean.False;
  118. col2.OptionsColumn.AllowMerge = DefaultBoolean.False;
  119.  
  120. gbDate.AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center; //这是合并表头居中显示
  121. gbWeekDay.AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center; //这是合并表头居中显示
  122. gbCol1.AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center; //这是合并表头居中显示
  123. gbCol2.AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center; //这是合并表头居中显示
  124.  
  125. }
  126. bandedGridView1.EndDataUpdate();
  127. bandedGridView1.EndUpdate();
  128. }
  129.  
  130. private void BandedGridView1_CustomDrawCell(object sender,
  131. RowCellCustomDrawEventArgs e)
  132. {
  133. var currentView = sender as BandedGridView;
  134. if (currentView == null) return;
  135.  
  136. var row = currentView.GetDataRow(e.RowHandle);
  137. if (row["RedColumnIndex"] != DBNull.Value && !string.IsNullOrWhiteSpace(e.CellValue.ToString()))
  138. {
  139. string[] args = row["RedColumnIndex"].ToString()
  140. .Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries);
  141. foreach (var arg in args)
  142. {
  143. if (e.Column.VisibleIndex == int.Parse(arg))
  144. {
  145. e.Appearance.BackColor = Color.Red;
  146. }
  147. }
  148. }
  149. if (row["GreenColumnIndex"] != DBNull.Value && !string.IsNullOrWhiteSpace(e.CellValue.ToString()))
  150. {
  151. string[] args = row["GreenColumnIndex"].ToString()
  152. .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  153. foreach (var arg in args)
  154. {
  155. if (e.Column.VisibleIndex == int.Parse(arg))
  156. {
  157. e.Appearance.BackColor = Color.Green;
  158. }
  159. }
  160. }
  161. }
  162.  
  163. DataTable GetData()
  164. {
  165. var list = InitColumnHeader();
  166. DataTable dt = new DataTable();
  167. dt.Columns.Add("StoreType");
  168. foreach (var item in list)
  169. {
  170. dt.Columns.Add("Date_WeekDay_col1_" + item.Date);
  171. dt.Columns.Add("Date_WeekDay_col2_" + item.Date);
  172. }
  173. dt.Columns.Add("RedColumnIndex");
  174. dt.Columns.Add("GreenColumnIndex");
  175. dt.Rows.Add("常温","8:00-9:00", "1000/800", "8:00-9:00", "1000/800", "8:00-9:00", "1000/800", "8:00-9:00",
  176. "1000/800", "8:00-9:00", "1000/800", "8:00-9:00", "1000/800", "8:00-9:00", "1000/800","2,4,6,8,10,12,14","");
  177. dt.Rows.Add("常温","8:00-9:00", "1000/800", "8:00-9:00", "1000/800", "8:00-9:00", "1000/800", "8:00-9:00",
  178. "1000/800", "8:00-9:00", "1000/800", "8:00-9:00", "1000/800", "8:00-9:00", "1000/800", "", "6,8,10,12,14");
  179. dt.Rows.Add("常温","8:00-9:00", "1000/800", "8:00-9:00", "1000/800", "8:00-9:00", "1000/800", "8:00-9:00",
  180. "1000/800", "8:00-9:00", "1000/800", "8:00-9:00", "1000/800", "8:00-9:00", "1000/800", "10,12,14","");
  181. dt.Rows.Add("冷冻", "8:00-9:00", "1000/800", "8:00-9:00", "1000/800", "8:00-9:00", "1000/800", "8:00-9:00",
  182. "1000/800", "8:00-9:00", "1000/800", "8:00-9:00", "1000/800", "8:00-9:00", "1000/800","","");
  183. dt.Rows.Add("冷冻", "8:00-9:00", "1000/800", "8:00-9:00", "1000/800", "8:00-9:00", "1000/800", "8:00-9:00",
  184. "1000/800", "8:00-9:00", "1000/800", "8:00-9:00", "1000/800", "8:00-9:00", "1000/800","","");
  185. dt.Rows.Add("冷冻", "8:00-9:00", "1000/800", "8:00-9:00", "1000/800", "8:00-9:00", "1000/800", "8:00-9:00",
  186. "1000/800", "8:00-9:00", "1000/800", "8:00-9:00", "1000/800", "8:00-9:00", "1000/800","","");
  187. return dt;
  188. }
  189.  
  190. public class ColumnHeaderInfo
  191. {
  192. public string Date { get; set; }
  193. public string WeekDay { get; set; }
  194. }
  195. }
  196. }

运行后的效果:

说明:

  • Demo数据仅为了展示,所以我在窗体代码里面写死了,绑定的动态数据源最好是DataTable类型,因为列名也是动态创建生成的,可扩展性比较强
  • 为了美观,设置了BrandedGridView的行高属性:BandPanelRowHeight表头高度,RowHeight每行数据单元格的行高
  • 需求中有预警设置指定单元格背景色的功能,以前用普通的DataGridView的时候,有CellFormating事件,处理比较方便,GridView控件里面有个类似的事件,叫CustomDrawCell,具体实现可参考以上代码

到此为止,基本上就实现了如何用代码动态创建生成复合表头的功能,希望可以对大家有所帮助,谢谢

基于DevExpress的BandedGridView动态生成多行(复合)表头的更多相关文章

  1. 编辑表格输入内容、根据input输入框输入数字动态生成表格行数、编辑表格内容提交传给后台数据处理

    编辑表格输入内容.根据input输入框输入数字动态生成表格行数.编辑表格内容提交传给后台数据处理 记录自己学习做的东西,写的小demo,希望对大家也有帮助! 代码如下: <!DOCTYPE ht ...

  2. Java获取后台数据,动态生成多行多列复选框

    本例目标: 获取后台数据集合,将集合的某个字段,比如:姓名,以复选框形式显示在HTML页面 应用场景: 获取数据库的人员姓名,将其显示在页面,供多项选择 效果如下: 一.后台 查询数据库,返回List ...

  3. winform中动态生成多行label,同时添加滚动条

    设计思路大概是这样的,Form内添加一个groupBox,groupBox内添加一个panel,panel的属性AutoScroll=true,在panel内动态添加label. 原始From如下: ...

  4. 分享我基于NPOI+ExcelReport实现的导入与导出EXCEL类库:ExcelUtility (续3篇-导出时动态生成多Sheet EXCEL)

    ExcelUtility 类库经过我(梦在旅途)近期不断的优化与新增功能,现已基本趋向稳定,功能上也基本可以满足绝大部份的EXCEL导出需求,该类库已在我们公司大型ERP系统全面使用,效果不错,今天应 ...

  5. 基于webpack的前端工程化开发解决方案探索(一):动态生成HTML(转)

    1.什么是工程化开发 软件工程的工程化开发概念由来已久,但对于前端开发来说,我们没有像VS或者eclipse这样量身打造的IDE,因为在大多数人眼中,前端代码无需编译,因此只要一个浏览器来运行调试就行 ...

  6. 论一种基于JS技术的WEB前端动态生成框图的方法

    前言 HTML是一种标记语言,由HTML的标签元素和文本编写的文档可被浏览器描述为一幅网页.通常情况下网页的实现是由HTML.CSS和Javascript三者结合完成的,HTML负责网页的结构,CSS ...

  7. DevExpress 中根据数据库字典动态生成卡式菜单 z

    第三方的Devexpress套件因为要使用权限机制控制不同用户进入系统显示菜单所以要配合字典数据动态生成.在WEB中这种问题灰常的轻松在winform里就稍微有点不同为了用DEV实现卡式菜单有组的概念 ...

  8. MSChart使用之动态生成多个多行ChartArea

    前台代码: <asp:Chart ID=" > <Titles> <asp:Title Name="Title1" runat=" ...

  9. Java利用poi生成word(包含插入图片,动态表格,行合并)

    转(小改): Java利用poi生成word(包含插入图片,动态表格,行合并) 2018年12月20日 09:06:51 wjw_11093010 阅读数:70 Java利用poi生成word(包含插 ...

随机推荐

  1. java基础解析系列(九)---String不可变性分析

    java基础解析系列(九)---String不可变性分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系列(二)---In ...

  2. Java 设计模式原则

    1.    找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起. 换句话说,如果每次新的需求一来,都会使某方面的代码发生变化,那么你就可以确定,这部分的代码需要抽出来,和其 ...

  3. Linux学习(四)单用户模式、救援模式、虚拟机克隆、linux互连(包括密匙登录)

    一.单用户模式 忘记root密码后,找回密码有两种方法: 单用户(grub没有加密的情况下可以使用) 救援模式 这一节我们先讲单用户模式   1.先重启(3种方法) reboot init 6 sho ...

  4. maximum shortest distance

    maximum shortest distance Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...

  5. 暑假练习赛 007 E - Pairs

    E - Pairs Description standard input/outputStatements In the secret book of ACM, it’s said: “Glory f ...

  6. java读写锁ReadWriteLock

    package com.java.concurrent; import java.util.concurrent.locks.ReadWriteLock; import java.util.concu ...

  7. BootStrap Table使用小结

    1.在当前表格的最后新增数据 $("#data_module_table").bootstrapTable('append', data.data);//data.data---- ...

  8. instanceof 原理

    运行流程 function instance_of(L, R) {                               //L 表示左表达式,R 表示右表达式   var O = R.prot ...

  9. Problem H: STL——括号匹配

    Description 给出一堆括号,看其是否匹配,例如 ().()().(()) 这样的括号就匹配,       )(.)()) 而这样的括号就不匹配 Input 每一行代表一组测试样例,每组测试样 ...

  10. 获取所有栈的信息,只有最上面的和最下面的,但是不能获取栈中间的activity信息

    直接在cmd窗口上输入 adb shell后,再输入dumpsys activity activities,可以看到所有的activity以及相关栈状态