使用C#在DatagridView中合并多个行标题

我有一个项目,我需要从数据库中查看Datagridview中的数据,它应该看起来像甘特图。

我想让Datagridview看起来像这样:

Datagridview示例

我已经尝试过很多来自互联网的代码,但没有任何工作正常

例如: https : //social.msdn.microsoft.com/Forums/windows/en-US/87004d70-482a-4b86-ba18-371670254b6a/how-to-merge-headers-in-a-datagridview?forum = winformsdatacontrols

此外,我不知道如何将日值输入单元格/行标题

这就是我从一个月开始的日子

int year = DateTime.Now.Year; int Jan = 1; int daysInJan = System.DateTime.DaysInMonth(year, Jan); 

链接的解决方案适用于它提供的示例。 那说:

我无法在标题下获得超过2列

从我们在评论中的讨论中,我认为只需添加额外的列宽就可以在超过2列上拉伸“主”标题就足够了。 这很好,直到我测试了足够的列以允许水平滚动。 就在那时,我注意到一个月的“主要”标题仅在该月的第一天列可见时显示。

以下代码将解决这些问题:

  1. 拉伸超过2列。
  2. 通过resize显示“主”标题,无论第1列可见性如何。
  3. 如何将日值输入单元格/行标题中

  4. IDisposable对象的一般清理和重构。

在表单中,要设置网格,请执行以下操作:

 private int[] daysInMonths; private void Form1_Load(object sender, EventArgs e) { int year = DateTime.Now.Year; daysInMonths = new int[12]; // Add a column for each day of the year; where // column name = the date (creates all unique column names) // column header text = the numeric day of the month for (int month = 1; month <= 12; month++) { daysInMonths[month - 1] = DateTime.DaysInMonth(year, month); // for days 1-31, 1-29, etc. for (int day = 1; day <= daysInMonths[month - 1]; day++) { DateTime date = new DateTime(year, month, day); DataGridViewTextBoxColumn col = new DataGridViewTextBoxColumn() { Name = date.ToString(), HeaderText = day.ToString(), Width = 20 }; this.dataGridView1.Columns.Add(col); } } // add some default rows for (int r = 0; r < 4; r++) { DataGridViewRow row = new DataGridViewRow(); row.CreateCells(this.dataGridView1); row.HeaderCell.Value = $"Project {r + 1}"; this.dataGridView1.Rows.Add(row); } this.dataGridView1.AllowUserToAddRows = false; this.dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders; this.dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing; this.dataGridView1.ColumnHeadersHeight = this.dataGridView1.ColumnHeadersHeight * 2; this.dataGridView1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.BottomCenter; this.dataGridView1.Paint += DataGridView1_Paint; this.dataGridView1.Scroll += DataGridView1_Scroll; this.dataGridView1.ColumnWidthChanged += DataGridView1_ColumnWidthChanged; this.dataGridView1.Resize += DataGridView1_Resize; } 

然后添加您的事件处理程序:

 private void InvalidateHeader() { Rectangle rtHeader = this.dataGridView1.DisplayRectangle; rtHeader.Height = this.dataGridView1.ColumnHeadersHeight / 2; this.dataGridView1.Invalidate(rtHeader); } private void DataGridView1_Resize(object sender, EventArgs e) { this.InvalidateHeader(); } private void DataGridView1_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e) { this.InvalidateHeader(); } private void DataGridView1_Scroll(object sender, ScrollEventArgs e) { this.InvalidateHeader(); } private void DataGridView1_Paint(object sender, PaintEventArgs e) { int col = 0; // For each month, create the display rectangle for the main title and draw it. foreach (int daysInMonth in daysInMonths) { Rectangle r1 = this.dataGridView1.GetCellDisplayRectangle(col, -1, true); // Start the rectangle from the first visible day of the month, // and add the width of the column for each following day. for (int day = 0; day < daysInMonth; day++) { Rectangle r2 = this.dataGridView1.GetCellDisplayRectangle(col + day, -1, true); if (r1.Width == 0) // Cell is not displayed. { r1 = r2; } else { r1.Width += r2.Width; } } r1.X += 1; r1.Y += 1; r1.Height = r1.Height / 2 - 2; r1.Width -= 2; using (Brush back = new SolidBrush(this.dataGridView1.ColumnHeadersDefaultCellStyle.BackColor)) using (Brush fore = new SolidBrush(this.dataGridView1.ColumnHeadersDefaultCellStyle.ForeColor)) using (Pen p = new Pen(this.dataGridView1.GridColor)) using (StringFormat format = new StringFormat()) { string month = DateTime.Parse(this.dataGridView1.Columns[col].Name).ToString("MMMM"); format.Alignment = StringAlignment.Center; format.LineAlignment = StringAlignment.Center; e.Graphics.FillRectangle(back, r1); e.Graphics.DrawRectangle(p, r1); e.Graphics.DrawString(month, this.dataGridView1.ColumnHeadersDefaultCellStyle.Font, fore, r1, format); } col += daysInMonth; // Move to the first column of the next month. } } 

在此处输入图像描述