2017-01-27 4 views
1
verschmelzen

Ich habe ein Projekt, wo ich Daten in Datagridview von einer Datenbank anzeigen muss und es sollte wie ein Gantt-Diagramm aussehen.Mehrere Zeilenköpfe in einer DatagridView mit C#

Ich möchte die Datagridview wie folgt aussehen lassen:

Datagridview example

ich bereits eine Menge Code aus dem Internet versucht, aber nichts funktionierte richtig

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

Auch ich weiß nicht, wie man die Tag Werte in die Zellen/Zeile Header

bekommen

Dies ist, wie ich die Tage von einem Monat erhalten

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

DGVS wird nicht lassen Sie das ohne viel Arbeit machen. Vielleicht ist es einfacher, alles auf ein Panel zu zeichnen? Welche Art von Benutzerinteraktion benötigen Sie? – TaW

+0

Worum ging es bei dem verknüpften Beispiel, das * nicht ordnungsgemäß funktioniert *? Abgesehen von den Headern, die sich ein wenig unbeholfen neu zentrierten, wenn sie vom Bildschirm weggescrollt wurden und [DoubleBuffered] sein mussten (http://stackoverflow.com/a/41894210/3773066), schien es so zu funktionieren, wie ich es erwartet hatte. – OhBeWise

Antwort

1

Die linked solution funktioniert gut für das Beispiel es bietet. Das heißt:

ich nicht in der Lage war mehr als 2 Spalten unter einem Titel in den Kommentaren

Aus unserer Diskussion zu bekommen, dachte ich, es reicht aus, dass man einfach zusätzliche Spaltenbreiten fügen eine strecken " Haupttitel über mehr als 2 Spalten. Das war in Ordnung, bis ich mit genügend Spalten getestet habe, um horizontales Scrollen zu erlauben. Es war dann, dass ich bemerkte, dass der "Haupt" Titel eines Monats nur angezeigt wurde, wenn die Tagesspalte dieses Monats sichtbar war.

Der folgende Code wird diese Probleme anzugehen:

  1. erstreckt sich über 2 + Spalten.
  2. Anzeige der "Haupt" Titel durch Größenanpassungen und unabhängig von 1 st Spalte Sichtbarkeit.
  3. , wie die Tageswerte in den Zellen/Zeilenkopf

  4. Allgemeine Bereinigung von IDisposable Objekte und Refactoring erhalten.

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

    Dann fügen Sie Ihre Event-Handler:


Im Formular, das Gitter tun folgende einzurichten

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. 
    } 
} 

enter image description here