11

I want to show the text in the header cells in vertical orientation. How can I do it?

Thanks

B.K.
  • 9,982
  • 10
  • 73
  • 105
Diego
  • 16,436
  • 26
  • 84
  • 136

4 Answers4

16

You can achieve the result you want using custom cell painting for the header.

In answer to your comment asking for a way to align the text with the bottom of the cell, I've added comments to my code. They are hopefully clear.

You need the following code (say in the Form_Load after initializing components)

dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
dataGridView1.ColumnHeadersHeight = 50;
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader;

// Here we attach an event handler to the cell painting event
dataGridView1.CellPainting += new DataGridViewCellPaintingEventHandler(dataGridView1_CellPainting);

Next you need something like the following code:

void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    // check that we are in a header cell!
    if (e.RowIndex == -1 && e.ColumnIndex >= 0)
    {
        e.PaintBackground(e.ClipBounds, true);
        Rectangle rect = this.dataGridView1.GetColumnDisplayRectangle(e.ColumnIndex, true);
        Size titleSize = TextRenderer.MeasureText(e.Value.ToString(), e.CellStyle.Font);
        if (this.dataGridView1.ColumnHeadersHeight < titleSize.Width)
        {
            this.dataGridView1.ColumnHeadersHeight = titleSize.Width;
        }

        e.Graphics.TranslateTransform(0, titleSize.Width);
        e.Graphics.RotateTransform(-90.0F);

        // This is the key line for bottom alignment - we adjust the PointF based on the 
        // ColumnHeadersHeight minus the current text width. ColumnHeadersHeight is the
        // maximum of all the columns since we paint cells twice - though this fact
        // may not be true in all usages!   
        e.Graphics.DrawString(e.Value.ToString(), this.Font, Brushes.Black, new PointF(rect.Y - (dataGridView1.ColumnHeadersHeight - titleSize.Width) , rect.X));

        // The old line for comparison
        //e.Graphics.DrawString(e.Value.ToString(), this.Font, Brushes.Black, new PointF(rect.Y, rect.X));


        e.Graphics.RotateTransform(90.0F);
        e.Graphics.TranslateTransform(0, -titleSize.Width);
        e.Handled = true;
    }
}
David Hall
  • 32,624
  • 10
  • 90
  • 127
  • Although, my usual caveat with changing the standard behaviour of the datagridview - do check if this is a must have. The control can be made to do a lot of things but often there are unexpected side effects that can rear their heads down the track. – David Hall Apr 25 '11 at 20:54
  • Thanks!! Do you now how to change this code to make the text be aligned at the bottom of the cell? – Diego Apr 26 '11 at 10:29
  • 1
    @Diego I've added code which aligns to the bottom of the cell, though again, do test this thoroughly, since it uses the fact that cell painting fires twice for the headers, which might not always be true. – David Hall Apr 26 '11 at 22:10
  • @DavidHall is that a way to make all cells vertically shown? not only column header. all cells shown vertically. – Ali Vojdanian Nov 16 '12 at 08:04
  • @aliboy38 please ask that as a separate question, perhaps with a link to this question as a comment so others can give you an answer. – David Hall Nov 16 '12 at 11:46
  • 4
    Thank you very much, I was able to use this. I should just add 2 notes: 1 - Use e.CellBounds instead of this.dataGridView1.GetColumnDisplayRectangle(...). The reason is that it is faster, and also for some reason I get visual artifacts when I access dataGridView1! 2 - To improve performance, enable double buffering (see http://stackoverflow.com/questions/4255148/how-to-improve-painting-performance-of-datagridview) – CaptainCodeman May 01 '14 at 10:32
5

A simpler and more effective renderer

Attach event either through designer, or with this line of code

dataGridView1.CellPainting += new DataGridView1_CellPainting(dataGridView1_CellPainting);

Event handler to draw rotated text

private void DataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e) {
    // Vertical text from column 0, or adjust below, if first column(s) to be skipped
    if (e.RowIndex == -1 && e.ColumnIndex >= 0) {
        e.PaintBackground(e.CellBounds, true);
        e.Graphics.TranslateTransform(e.CellBounds.Left , e.CellBounds.Bottom);
        e.Graphics.RotateTransform(270);
        e.Graphics.DrawString(e.FormattedValue.ToString(),e.CellStyle.Font,Brushes.Black,5,5);
        e.Graphics.ResetTransform();
        e.Handled = true;
    }
}
TFD
  • 23,890
  • 2
  • 34
  • 51
-1
DataGrid d = new DataGrid();
d.Columns[0].HeaderStyle.VerticalAlign = VerticalAlign.Bottom;

If you are looking for gridview then you case like this :-

GridView gv = new GridView ();
gv.Columns[0].ItemStyle.VerticalAlign = VerticalAlign.Bottom;

If you are looking for datagridview then you case like this :- Create an object of datagridview.

gv.Columns["ColumnName"].HeaderCell.Style.Alignment = DataGridViewContentAlignment.BottomCenter;
sobby01
  • 1,916
  • 1
  • 13
  • 22
  • @TechGiant: The second line for a DataGridView throws 2 errors: 'System.Windows.Forms.DataGridViewColumn' does not contain a definition for 'ItemStyle' and no extension method 'ItemStyle' accepting a first argument of type 'System.Windows.Forms.DataGridViewColumn' could be found (are you missing a using directive or an assembly reference) and: The name 'VerticalAlign' does not exist in the current context – Diego Apr 25 '11 at 20:24
  • @Diego - for datagridview i have written last line . Try the last line that will give your result – sobby01 Apr 25 '11 at 20:25
  • @TechGiant: Also doen't compile: Non-invocable member 'System.Windows.Forms.DataGridView.Columns' cannot be used like a method. – Diego Apr 25 '11 at 20:27
  • Hey now try the last line actually need to use like gv.Columns["ColumnName"] not gv.Columns("ColumnName")..I have tried that works.... – sobby01 Apr 25 '11 at 20:34
  • @Diego- May i know why you want to make header text vertical ? – sobby01 Apr 25 '11 at 20:48
  • Because the designer said so :( – Diego Apr 25 '11 at 20:51
  • Buddy try the above post... i have run the code and headers come as you want ...... :) – sobby01 Apr 25 '11 at 20:56
-1
void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
   {
           if (e.RowIndex == -1 && e.ColumnIndex >= 0)
           {
               e.PaintBackground(e.ClipBounds, true);
               Rectangle rect =
this.dataGridView1.GetColumnDisplayRectangle(e.ColumnIndex, true);
               Size titleSize =
TextRenderer.MeasureText(e.Value.ToString(), e.CellStyle.Font);
               if (this.dataGridView1.ColumnHeadersHeight <
titleSize.Width)
                   this.dataGridView1.ColumnHeadersHeight =
titleSize.Width;

               e.Graphics.TranslateTransform(0, titleSize.Width);
               e.Graphics.RotateTransform(-90.0F);

               e.Graphics.DrawString(e.Value.ToString(), this.Font,
Brushes.Orange, new PointF(rect.Y, rect.X));

               e.Graphics.RotateTransform(90.0F);
               e.Graphics.TranslateTransform(0, -titleSize.Width);
               e.Handled = true;
           }
  }

In addition, you could set the AutoSizeColumnsMode property of the
DataGridView to AllCellsExceptHeader in order to make the DataGridView
compact.
sobby01
  • 1,916
  • 1
  • 13
  • 22