user1697111
user1697111

Reputation: 199

Changing Winforms DataGridView ToolTip font

I have DataGridView in my program on which I compose a custom ToolTip under MouseMove, like this...

Private Sub dgv_dokument_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles dgv_dokument.MouseMove

    Dim hit As DataGridView.HitTestInfo = dgv_dokument.HitTest(e.X, e.Y)

    If hit.Type = DataGridViewHitTestType.Cell Then
        If hit.ColumnIndex >= 0 AndAlso hit.RowIndex >= 0 Then
            Dim s As Integer = Convert.ToInt32(dgv_dokument.Item(co.GetColIndex(dgv_dokument, "myNumCol"), hit.RowIndex).Value)
            Dim ttText As String = ""
            If s > 0 Then
                Dim sb As New StringBuilder
                get_data(s, sb)
                ttText = sb.ToString
            End If

            dgv_dokument.Item(hit.ColumnIndex, hit.RowIndex).ToolTipText = ttText
            Exit Sub
        End If
    End If
End Sub

Under get_data(s, sb) I filled StringBuilder with strings in mean of "column" formatted data, like this...

   sb.Append(code.ToString.PadLeft(5) + " ")
   sb.Append(name.Trim.PadRight(27) + " ")
   sb.Append(meas.Trim.PadRight(3) + " ")
   sb.Append(qty.ToString("N2").PadLeft(10) + " ")
   sb.Append(price.ToString("N2").PadLeft(12))
   sb.Append(Environment.NewLine)

That all works good except that I would like to see my tooltip column-aligned. That may be done with using proportional font in ToolTop.

Can I somehow (and how) determine other than default font for just DataGridView's ToolTip's? For example "Courier New".

Upvotes: 2

Views: 3124

Answers (1)

TaW
TaW

Reputation: 54433

You need to OwnerDraw the ToolTip.

Here is an example:

First set the property OwnerDraw = true for the ToolTip.

Then code its Draw event, maybe like this:

private void toolTip1_Draw(object sender, DrawToolTipEventArgs e)
{
    e.DrawBackground();
    e.DrawBorder();
    using (Font f = new Font("Consolas", 8f))
        e.Graphics.DrawString(e.ToolTipText, f, SystemBrushes.ControlText, e.Bounds);
}

enter image description here

Note that if your Fonts get smaller than the default (as mine) some extra free space will show, which is pretty much OK.

But if it is larger the Bounds may need to adapt, which can get somewhat tricky. You would have to pad the text with enough room to the end and bottom to enforce a sufficient Bounds size.

For this you would have to measure the space needed for the larger Font and add spaces until the Bounds have grown enough. No need to remove them as overdrawing spaces will not be a problem; but sticking with the original e.Font certainly is a lot easier.

You still may find the need to add a few spaces: Your fixed font will, on average, take a little more space so the Bounds provided may turn out to be a little tight anyway..

Update

Since you are using a DataGridView you need a few extras to consider:

  • The DGV is geared towards showing its own cell related ToolTips. But they don't have an accessible draw event; so we can't use them. so we turn them off: dataGridView.ShowCellToolTips = false;

  • Since we need to show a different one for each cell we need to show them we need to detect when we are over a new cell. The DGV doesn't have a different text for each cell, although the cells have theirs, but won't hand it to the external ToolTip. So we can code the MouseMove event, maybe like this:


private void dataGridView1_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e)
{
    if (e.ColumnIndex < 0 || e.RowIndex < 0 
     || dataGridView1[e.ColumnIndex, e.RowIndex].Value == null) return;

    // use your own function to set the text!
    string s = dataGridView1[e.ColumnIndex, e.RowIndex].Value.ToString();
    // check for changes to prevent flicker!
    if (s == toolTip1.GetToolTip(dataGridView1)) return;

    toolTip1.SetToolTip(dataGridView1, s); 
}

Note that the remarks about padding with spaces to make the text fit in the bounds still applies..

Upvotes: 1

Related Questions