Search code examples
c#winformsdatagrid

Change font for a particular row in System.Windows.Forms.DataGrid


For various reasons I'm using the obsolete System.Windows.Forms.DataGrid instead of DataGridView, and I need to make a particular row bold, while the others remain unbolded.

Both the row header text and the cells should be bold. I assume this is done by changing the font somehow. The only properties I found were Font and HeaderFont but they change the font for the entire control.


Solution

  • You can create a new DataGridColumnStyle and override its Paint methods and apply your custom paint logic to customize painting of cell. You can derive from DataGridTextBoxColumn and override this overload of Paint.

    You can use rowNum parameter which contains the row number which you are painting. Also you can extract the value of cell using source parameter use it to decide how render the cell.

    public class MyDataGridTextBoxColumn : DataGridTextBoxColumn
    {
        protected override void Paint(Graphics g, Rectangle bounds, CurrencyManager source,
           int rowNum, Brush backBrush, Brush foreBrush, bool alignToRight)
        {
            if (rowNum == 1) /*Specific row index*/
            {
                var value = this.PropertyDescriptor.GetValue(source.List[rowNum]);
                var text = string.Format("{0}", value);
                Rectangle rect = bounds;
                using (var format = new StringFormat())
                {
                    if (alignToRight)
                        format.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
                    format.Alignment = (this.Alignment == HorizontalAlignment.Left) ?
                        StringAlignment.Near :
                        ((this.Alignment == HorizontalAlignment.Center) ?
                        StringAlignment.Center : StringAlignment.Far);
                    format.FormatFlags |= StringFormatFlags.NoWrap;
                    g.FillRectangle(backBrush, rect);
                    rect.Offset(0, 2);
                    rect.Height -= 2;
                    var font = new Font(this.DataGridTableStyle.DataGrid.Font, FontStyle.Bold);
                    g.DrawString(text, font, foreBrush, rect, format);
                }
            }
            else
                base.Paint(g, bounds, source, rowNum, backBrush, foreBrush, alignToRight);
        }
    }
    

    And here is the usage:

    var dt = new DataTable();
    dt.Columns.Add("A");
    dt.Columns.Add("B");
    dt.Rows.Add("1", "11");
    dt.Rows.Add("2", "22");
    dt.Rows.Add("3", "33");
    
    var dg = new DataGrid();
    dg.Dock = DockStyle.Fill;
    var ts = new DataGridTableStyle();
    ts.GridColumnStyles.Add(new MyDataGridTextBoxColumn() 
        { MappingName = "A", HeaderText = "A" });
    ts.GridColumnStyles.Add(new MyDataGridTextBoxColumn() 
        { MappingName = "B", HeaderText = "B" });
    dg.TableStyles.Add(ts);
    
    this.Controls.Add(dg);
    dg.DataSource = dt;
    dg.BringToFront();