.NET DataGridView: Remove "current row" black triangle
Asked Answered
D

11

16

In the DataGridView, even if you set the grid as readonly there is a black triangle at the rows headers which is shown at the current row.

I'd like to avoid it to be shown, also I'd like to avoid the big padding of those cells caused by the triangle. I guess the padding is caused by the triangle because the cell's padding is 0.

Is it posible to do that? How?

Thanks!

Edit

This is how row headers text is created:

for (int i = 0; i < 5; i++)
{
    DataGridViewRow row = new DataGridViewRow();
    row.HeaderCell.Value = headers[i];
    dataGridView1.Rows.Add(row);
}

and headers its a simply array of strings. (string[])

Deltoid answered 28/4, 2011 at 21:12 Comment(0)
L
20
  • If you want to keep the row headers rather than hide them, then you can use the cell padding to push the triangle out of sight:

    this.dataGridView1.RowHeadersDefaultCellStyle.Padding = 
        new Padding(this.dataGridView1.RowHeadersWidth);
    
  • If you are using row header text and want keep that visible you need to use some custom painting - thankfully very simple. After the above code, simply attach to the RowPostPaint event as shown below:

    dataGridView1.RowPostPaint += 
        new DataGridViewRowPostPaintEventHandler(dataGridView1_RowPostPaint);
    

    And in the RowPostPaint method:

    void dataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
    {
        object o = dataGridView1.Rows[e.RowIndex].HeaderCell.Value;
    
        e.Graphics.DrawString(
            o != null ? o.ToString() : "",
            dataGridView1.Font, 
            Brushes.Black, 
            new PointF((float)e.RowBounds.Left + 2, (float)e.RowBounds.Top + 4));
    }
    

    As Dan Neely points out the use of Brushes.Black above will overwrite any existing changes, so it is better for the brush to use:

    new SolidBrush(dataGridView1.RowHeadersDefaultCellStyle.ForeColor)
    
Locris answered 28/4, 2011 at 21:48 Comment(8)
THis works great for the triangle, but it also moves the header text, I'd like to have the text and not the triangle, is that posible?Deltoid
@Deltoid Hi, Not sure what you mean by the text in the row headers. Like Joe, I've never seen this. Could you please edit your question with the code that creates this text and I'll take a look.Locris
@Deltoid wow, just goes to show you how many options there are in the DataGridView - I've been using it for years and never seen HeaderCell.Value used. I've added to my answer some code that keeps the text.Locris
@David Hall You should use new SolidBrush(dataGridView1.RowHeadersDefaultCellStyle.ForeColor) to maintain any style changes instead of defaulting to black. The latter will also cause problems on any system where a theme has changed the color of WindowsText.Condyle
@Dan Neely thanks for the suggestion - when coming up with answers on slightly unusual things like this I"m often just finding some code that works without having tried it myself in a real environment so every little bit of best-practice input helps!Locris
@David Hall nod it wasn't something I ever thought about either until I had a tester who changed all the default colors on her box. Now except when I need an explicit color for something I always go for the SystemColors stuff.Condyle
There is e.FormattedValue and ideally it would be good to translate text alignment etc... I did e.Graphics.DrawString((string)e.FormattedValue, e.CellStyle.Font, new SolidBrush(e.CellStyle.ForeColor), new RectangleF(e.CellBounds.X + 2, e.CellBounds.Y, e.CellBounds.Width - 2, e.CellBounds.Height - 1), new StringFormat { LineAlignment = StringAlignment.Center, Trimming = StringTrimming.EllipsisCharacter, FormatFlags = StringFormatFlags.LineLimit }); for my particular case - you can see it has alignment and padding mentioned, but hardcoded. You can refer to e.CellStyle.Inanimate
As it appeared two strings one near to other, I added e.Graphics.FillRectangle(new SolidBrush(dataGridView1.RowHeadersDefaultCellStyle.BackColor), e.RowBounds.Left + 1, e.RowBounds.Top + 1, dataGridView1.Rows[e.RowIndex].HeaderCell.Size.Width - 2, dataGridView1.Rows[e.RowIndex].HeaderCell.Size.Height - 2); before e.Graphics.DrawString(...)Ardeb
R
8

Set RowHeadersVisible to false.

Rhoads answered 28/4, 2011 at 21:22 Comment(4)
@Jow White: I want to be able to see the headers and also headers text, I just don't want the annoyng triangle.Deltoid
sorry for the typo in your name.Deltoid
I've never seen text in the row headers -- just the triangle. Are you confusing row headers (at the left side of each row, with the gray box and triangle) with column headers (the names at the top of each column)?Rhoads
Nope, I have a double-entry table so I do have text in my row headers. I'm not sure if double-entry table is the right expression in english.Deltoid
P
5

A very simple solution is to set the row height to 16 pixels or less. This disables all icons in the row header cell.

dataGridView1.RowTemplate.Height = 16;
Potemkin answered 20/4, 2016 at 14:21 Comment(2)
This worked for me. I like to put line numbers on the row header. The glyph was pushing the numbers to the right so I would have to make the row header wider than I wanted. This is a bug. The Microsoft documentation states that the headercell value will push the glyph off the screen if there is not enough room for both. What actually happens is the opposite: The glyph pushes the headercell.value off. And disabling showediticon does not work eitherExpulsion
Additionally you have to forbid row resizing. Otherwise the user resizes the row and the problem is back.Claxton
E
2

Triangle problem , it's simple ,put

dgv_Products.Rows[xval].Selected = true;
dgv_Products.CurrentCell  = dgv_Products.Rows[xval].Cells[0];

that is make current cell property to the cell zero of current selected row.( Tested working for dgv_Products.MultiSelect = false ; )

Effluvium answered 23/3, 2012 at 13:14 Comment(1)
Thank you, the problem with multiselect random rows has disappearedSporogonium
F
2
dataGridView1.CurrentCell = null;

Will remove the black arrow completely.

You need to run this line every time the data in the DataGridView is updated.

Feldstein answered 15/11, 2013 at 19:21 Comment(1)
Thanks, this is a better solution than "dataGridView1.ClearSelection();"Ecclesia
W
2

The DataGridViewRowPostPaintEventArgs includes this particular PaintHeader method:

PaintHeader(DataGridViewPaintParts) - Paints the specified parts of the row header of the current row.

This is the DataGridViewPaintParts Enumeration: https://msdn.microsoft.com/en-us/library/ms159092%28v=vs.110%29.aspx

So what you do is in your datagridview's RowPostPaint event, first tell it to only paint the background of the row's header...like so:

e.PaintHeader(DataGridViewPaintParts.Background)

Then tell it to draw in whatever string you want it to. Here is my example:

Private Sub MyDGV_RowPostPaint(sender As Object, e As DataGridViewRowPostPaintEventArgs) Handles dgvData.RowPostPaint

    Dim grid As DataGridView = DirectCast(sender, DataGridView)

    e.PaintHeader(DataGridViewPaintParts.Background)

    Dim rowIdx As String = (e.RowIndex + 1).ToString()

    Dim rowFont As New System.Drawing.Font("Segoe UI", 9.0!, _
        System.Drawing.FontStyle.Bold, _
        System.Drawing.GraphicsUnit.Point, CType(0, Byte))

    Dim centerFormat = New StringFormat()
    centerFormat.Alignment = StringAlignment.Far
    centerFormat.LineAlignment = StringAlignment.Near

    Dim headerBounds As Rectangle = New Rectangle(e.RowBounds.Left, e.RowBounds.Top, grid.RowHeadersWidth, e.RowBounds.Height)

    e.Graphics.DrawString(rowIdx, rowFont, SystemBrushes.ControlText, headerBounds, centerFormat)

End Sub
Whitelivered answered 6/5, 2015 at 16:57 Comment(1)
Creating a new font for each drawing is a huge unnecessary overhead.Claxton
S
1

In case someone still wants to know:

dataGridView1.RowHeadersWidth = 4; // the left row header size.

This will take away the triangle and narrow down the default size.

Hope that helps.

Spunky answered 14/9, 2012 at 23:46 Comment(1)
Does not work, sorry.Ecclesia
A
0

Set RowHeadersVisible to false, and add a column in front instead. Seems to be the easiest way

Anodize answered 20/10, 2023 at 11:54 Comment(0)
P
0

David Halls answer modified to centre align the text

// Subscribe to the post paint event
dgv.RowPostPaint += new DataGridViewRowPostPaintEventHandler(dgv_RowPostPaint);

// Push the triangle (and text) off the cell
dgv.RowHeadersDefaultCellStyle.Padding = new Padding(this.dgv.RowHeadersWidth);

// Each row has its header cell text measured. The width of the row header and the width
// of the text are calculated to form an offset to push the text right (or left if the 
// text is to wide!) off of the cell boundary left edge
void dgv_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
string text = dgv.Rows[e.RowIndex].HeaderCell.Value.ToString();

Size textSize = TextRenderer.MeasureText(text, dgv.Rows[e.RowIndex].Cells[0].InheritedStyle.Font);

float fudgeOffset = 1.0F;

float offset = (dgv.RowHeadersWidth - textSize.Width) / 2 ;

e.Graphics.DrawString(
    text != null ? text : "",
    dgv.Font,
    new SolidBrush(dgv.RowHeadersDefaultCellStyle.ForeColor),
    new PointF((float)e.RowBounds.Left + fudgeOffset + offset, (float)e.RowBounds.Top + 4));
}
Personality answered 21/3, 2024 at 20:59 Comment(0)
C
-1

Tried other answers, but i couldn't be able to match same font appearance with columns font. And I've found a solution on Microsoft Forums

First subscribe the DataGridView.CellPainting like;

dgv.CellPainting += Dgv_CellPainting;

Then print the text what ever you want(original post has got row index);

private void Dgv_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            if (e.ColumnIndex == -1 && e.RowIndex > -1)
            {
                object o = (sender as DataGridView).Rows[e.RowIndex].HeaderCell.Value;
                e.PaintBackground(e.CellBounds, true);

                using (SolidBrush br = new SolidBrush(Color.Black))
                {
                    StringFormat sf = new StringFormat();
                    sf.Alignment = StringAlignment.Center;
                    sf.LineAlignment = StringAlignment.Center;
                    e.Graphics.DrawString(o.ToString(),
                    e.CellStyle.Font, br, e.CellBounds, sf);
                }
                e.Handled = true;
            }
        }
Couplet answered 28/7, 2019 at 15:57 Comment(0)
P
-4
 'Datagridview'.rowheadervisible=false 

To hide black arrow row selecter ma bob

Datagridview is the name of your datagrid without the quotes '' so.... If your grid is named Example then

 Example.rowheadervisible=false
Perversion answered 29/11, 2016 at 15:43 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.