none
ToolTip Font Change?

    Question

  • Is it possible to custom set up the .Bold property as well as to manipulate the font size for ToolTip objects?

     

    Thanks

    Friday, May 18, 2007 2:46 PM

Answers

  • You could create a derived Tooltip class and handle the Draw() event:

     

     

    Code Snippet

    Public Class MyTooltip

       Inherits ToolTip

       Sub New()

          MyBase.New()

          Me.OwnerDraw = True

          AddHandler Me.Draw, AddressOf OnDraw

       End Sub

       Public Sub New(ByVal Cont As System.ComponentModel.IContainer)

          MyBase.New(Cont)

          Me.OwnerDraw = True

          AddHandler Me.Draw, AddressOf OnDraw

       End Sub

       Private Sub OnDraw(ByVal sender As Object, ByVal e As DrawToolTipEventArgs)

          Dim newArgs As DrawToolTipEventArgs = New DrawToolTipEventArgs( _

             e.Graphics, _

             e.AssociatedWindow, _

             e.AssociatedControl, _

             e.Bounds, _

             e.ToolTipText, _

             Me.BackColor, _

             Me.ForeColor, _

             New Font(e.Font, FontStyle.Bold))

     

          newArgs.DrawBackground()

          newArgs.DrawBorder()

          newArgs.DrawText()

    End Sub

    End Class

     

     

    Of course you can specify whatever font you want as the template for the Font parameter.

     

    Marc.

    Friday, May 18, 2007 4:34 PM

All replies

  • You could create a derived Tooltip class and handle the Draw() event:

     

     

    Code Snippet

    Public Class MyTooltip

       Inherits ToolTip

       Sub New()

          MyBase.New()

          Me.OwnerDraw = True

          AddHandler Me.Draw, AddressOf OnDraw

       End Sub

       Public Sub New(ByVal Cont As System.ComponentModel.IContainer)

          MyBase.New(Cont)

          Me.OwnerDraw = True

          AddHandler Me.Draw, AddressOf OnDraw

       End Sub

       Private Sub OnDraw(ByVal sender As Object, ByVal e As DrawToolTipEventArgs)

          Dim newArgs As DrawToolTipEventArgs = New DrawToolTipEventArgs( _

             e.Graphics, _

             e.AssociatedWindow, _

             e.AssociatedControl, _

             e.Bounds, _

             e.ToolTipText, _

             Me.BackColor, _

             Me.ForeColor, _

             New Font(e.Font, FontStyle.Bold))

     

          newArgs.DrawBackground()

          newArgs.DrawBorder()

          newArgs.DrawText()

    End Sub

    End Class

     

     

    Of course you can specify whatever font you want as the template for the Font parameter.

     

    Marc.

    Friday, May 18, 2007 4:34 PM
  •  Malacki wrote:

    You could create a derived Tooltip class and handle the Draw() event:

     

     

    Code Snippet

    Public Class MyTooltip

       Inherits ToolTip

       Sub New()

          MyBase.New()

          Me.OwnerDraw = True

          AddHandler Me.Draw, AddressOf OnDraw

       End Sub

       Public Sub New(ByVal Cont As System.ComponentModel.IContainer)

          MyBase.New(Cont)

          Me.OwnerDraw = True

          AddHandler Me.Draw, AddressOf OnDraw

       End Sub

       Private Sub OnDraw(ByVal sender As Object, ByVal e As DrawToolTipEventArgs)

          Dim newArgs As DrawToolTipEventArgs = New DrawToolTipEventArgs( _

             e.Graphics, _

             e.AssociatedWindow, _

             e.AssociatedControl, _

             e.Bounds, _

             e.ToolTipText, _

             Me.BackColor, _

             Me.ForeColor, _

             New Font(e.Font, FontStyle.Bold))

     

          newArgs.DrawBackground()

          newArgs.DrawBorder()

          newArgs.DrawText()

    End Sub

    End Class

     

     

    Of course you can specify whatever font you want as the template for the Font parameter.

     

    Marc.

     

    Thank you Marc. Much appreciated.

     

    Friday, May 18, 2007 6:32 PM
  • Also I converted Marc's VB code to C# and had to resolve a small problem. It turns out the builder does not appreciate the fact that the font size is being changed metrically and the client rectangle of the tooltip becomes too small for bold text in many cases. Padding with a few blanks does a perfect job. The final product looks great. Thanks again, Marc.

    public class MyTooltip : ToolTip
        {
            public MyTooltip ( )
            {
                this.OwnerDraw = true;
                this.Draw += new DrawToolTipEventHandler ( OnDraw );
            }                                                                                               //  MyTooltip

            public MyTooltip ( System.ComponentModel.IContainer Cont )
            {
                this.OwnerDraw = true;
                this.Draw += new DrawToolTipEventHandler ( OnDraw );
            }                                                                                               //  MyTooltip

            private void OnDraw ( object sender, DrawToolTipEventArgs e )
            {
                DrawToolTipEventArgs newArgs = new DrawToolTipEventArgs ( e.Graphics,
                    e.AssociatedWindow, e.AssociatedControl, e.Bounds, e.ToolTipText,
                    this.BackColor, this.ForeColor, new Font ( e.Font, FontStyle.Bold ) );
                newArgs.DrawBackground ( );
                newArgs.DrawBorder ( );
                newArgs.DrawText ( TextFormatFlags.TextBoxControl );
            }                                                                                               //  OnDraw
        }                                                                                               //  class MyTooltip

     

    Sunday, May 20, 2007 11:32 AM
  • Glad I could help Smile

    Marc

    Sunday, May 20, 2007 1:11 PM
  •  

    Hi,

     

    I used the C# class MyTooltip that AlexB posted. But somehow it doesn't work because still the original font is shown (as if I am still using .NET's ToolTip). In fact, setting a breakpoint in the OnDraw method of MyTooltip will never be reached. What could be wrong here?

     

    This is how I use the class MyTooltip

     

    MyTooltip tooltip = new MyTooltip();

    tooltip.IsBalloon = true;

    tooltip.ToolTipTitle = some_title_text;

    tooltip.SetToolTip(some_panel, some_text);

     

    Again, the fragment above has the same outcome as if I was using the original ToolTip from the .NET framework.

    Monday, November 05, 2007 3:56 PM
  •  MarkyMark unique attempt#5847 wrote:

     

    Hi,

     

    I used the C# class MyTooltip that AlexB posted. But somehow it doesn't work because still the original font is shown (as if I am still using .NET's ToolTip). In fact, setting a breakpoint in the OnDraw method of MyTooltip will never be reached. What could be wrong here?

     

    This is how I use the class MyTooltip

     

    MyTooltip tooltip = new MyTooltip();

    tooltip.IsBalloon = true;

    tooltip.ToolTipTitle = some_title_text;

    tooltip.SetToolTip(some_panel, some_text);

     

    Again, the fragment above has the same outcome as if I was using the original ToolTip from the .NET framework.

     

    Yep, this does happen. It is amazing, after 3-6 month the problem is completely forgotten and you have hard time to figure out what it is all about. It is s simple problem. If I am not mistaken (I will double check on that) the property that is screwing up your code is

     

    tooltip.IsBalloon = true;

     

    MyToolTip does not balloon. So, remove it.

     

    If I am wrong, let me know, I will check my code.

    Monday, November 05, 2007 6:17 PM
  • Hi Alex,

     

    Yes thanks, that's it. IsBalloon was the problem. When removing this statement then MyTooltip.OnDraw gets called. I also noticed that other properties like ToolTipIcon and ToolTipTitle don't appear in the tooltip. It is a bit unfortunate that I cannot use these tooltip enhancements when using the class MyTooltip. Oh well, I'll survive. My code is now simplied to:

     

    MyTooltip tooltip = new MyTooltip();

    tooltip.SetToolTip(some_panel, some_text);

     

    Ok, so now I can change the font of the tooltip but a new problem comes up that you have already addressed in an earlier posting; my tooltip text (5 lines) does not fit in the client rectangle. You mentioned "Padding with a few blanks does a perfect job" but I am wondering how to get the control of the actual tooltip to add padding to. Maybe you meant adding blanks/spaces to e.ToolTipText but I tried this and it didn't help. Anyway, the word "few" worries me a little as well. I tried to solve this issue by adding the following code to OnDraw (in bold):

     

    private void OnDraw(object sender, DrawToolTipEventArgs e)

    {

    // The font to use for this type of tooltip

    Font newFont = new Font("Arial", 11);

     

    // Determine the size required to fit the text into the tooltip's client rectangle, giving the font to be used

    SizeF size = e.Graphics.MeasureString(e.ToolTipText, newFont);

     

    DrawToolTipEventArgs newArgs =

    new DrawToolTipEventArgs(e.Graphics,

    e.AssociatedWindow,

    e.AssociatedControl,

    //e.Bounds,

    new Rectangle(0, 0, Convert.ToInt32(size.Width), Convert.ToInt32(size.Height)),

    e.ToolTipText,

    this.BackColor,

    this.ForeColor,

    newFont);

     

    newArgs.DrawBackground();

    newArgs.DrawBorder();

    newArgs.DrawText(TextFormatFlags.TextBoxControl);

    }

     

    Although the new rectangle is wider and higher than e.Bounds as I expected, the tooltip unfortunately has still the same size as before. I also tried several setting regarding TextFormatFlags but again, no success. The client rectangle remains its original size but this time there is no border drawn at the right and bottom side of the tooltip, because the new rectangle is bigger.

     

    Could you please clarify how you adjusted the client rectangle the way you did by using padding so that the text fits in the tooltip? Any help is appreciated.

     

    Regards, Mark

     

    Tuesday, November 06, 2007 11:15 AM
  •  MarkyMark unique attempt#5847 wrote:

    Hi Alex,

     

    Yes thanks, that's it. IsBalloon was the problem. When removing this statement then MyTooltip.OnDraw gets called. I also noticed that other properties like ToolTipIcon and ToolTipTitle don't appear in the tooltip. It is a bit unfortunate that I cannot use these tooltip enhancements when using the class MyTooltip. Oh well, I'll survive. My code is now simplied to:

     

     

     

    Thanks Mark, I am very much interesed in the outcome of your research. Keep me posted. The way I solved it is simple. I have about two dozen such instances and I developed a sort of a formula to enlarge the width of the toolTip.Text message. I am not very clear now but I think it did not really work in a sense that it was not convenient and I just resorted to this:

     

    this.toolTip1.SetToolTip ( btn,

    "RESTORE MINMAX ANALYSIS for " + symbol + "              \r\n" +

    "From a Previously Stored Sql File                         " );

     

    or

     

    this.toolTip1.SetToolTip ( btn, "ANALYZE THIS PAGE FOR MIN AND MAX                           " );

     

    You do it empirically so to speak. However now after you brought my attention to this issue I suggest you should try this: There should be a way to get exact metric of each System.Drawing.Font with all attributes. That may give you a formula to do it sensibly. I am too buys now with some other urgent stuff and do not feel presdured to improve what is already well set. But I will be interested in your result if you've pursued it.

    Tuesday, November 06, 2007 1:27 PM
  • Ok, I have found a solution to display the tooltip in a specified font where the bounds of the tooltip rectangle are correct.

     

    The solution is that besides the Draw event also the Popup event should be handled. This event is fired before the tooltip is initially displayed. Here the size of the rectangle can be set to the proper bounds using the MeasureString API. This size will be adopted by DrawToolTipEventArgs.Bounds within of the Draw delegate.

     

    Alex, I'm still interested in the solution you applied using padding. Here is my solution using the Popup event.

     

    public class MyTooltip : System.Windows.Forms.ToolTip

    {

    private Font _font = null;

     

    public MyTooltip (Font font) : base()

    {

    _font = font;

     

    this.OwnerDraw = true;

    this.Draw += new DrawToolTipEventHandler(OnDraw);

    this.Popup += new PopupEventHandler(OnPopup);

    }

     

    private void OnPopup(object sender, PopupEventArgs e)

    {

    if (this.IsBalloon)

    {

    throw new Exception("The class MyTooltip does not support balloon tooltips.");

    }

     

    SizeF size = e.AssociatedControl.CreateGraphics().MeasureString(this.GetToolTip(e.AssociatedControl), _font);

     

    e.ToolTipSize = new Size(Convert.ToInt32(size.Width), Convert.ToInt32(size.Height));

    }

     

    private void OnDraw(object sender, DrawToolTipEventArgs e)

    {

    DrawToolTipEventArgs newArgs = new DrawToolTipEventArgs(e.Graphics,

    e.AssociatedWindow,

    e.AssociatedControl,

    e.Bounds,

    e.ToolTipText,

    this.BackColor,

    this.ForeColor,

    _font);

     

    newArgs.DrawBackground();

    newArgs.DrawBorder();

    newArgs.DrawText(TextFormatFlags.TextBoxControl);

    }

    }

     

    Well, I am not completely satisfied yet though. My solution may present the tooltip in a specified font in a properly bounded client rectangle but depending on the location where the tooltip is shown, the tooltip could appear partly off screen while normally the tooltip repositions itself to be fully on screen. Maybe your solution Alex using padding comes in helpful here. It seems that my work will never be finished; I knew I should have been a truck driver...

     

    Mark

     

     

    Tuesday, November 06, 2007 2:09 PM
  • Alex, I have read your posting after I sent my last post so we kind of crossed.

     

    I tried your way by adding addional spaces to the tooltip text but somehow this didn't work for me. 

     

    Anyways, I have used MeasureString API that will present me the metrics of the text when using the specified font, taking into account whether or not a font is truetype.

     

    Like I concluded in my last post; all I have to do now is to reposition the tooltip somehow when it is about to be shown partly off screen.

     

    Regards,

    Mark

    Tuesday, November 06, 2007 2:42 PM
  •  MarkyMark unique attempt#5847 wrote:

    Alex, I have read your posting after I sent my last post so we kind of crossed.

     

    I tried your way by adding addional spaces to the tooltip text but somehow this didn't work for me. 

     

    Anyways, I have used MeasureString API that will present me the metrics of the text when using the specified font, taking into account whether or not a font is truetype.

     

    Like I concluded in my last post; all I have to do now is to reposition the tooltip somehow when it is about to be shown partly off screen.

     

    Regards,

    Mark

     

    Thank you, Mark. It is very helpful what you've done. I will study it. It is strange, my "padding solution" did not work for you. There should be other differences in your control, I guess.

    Tuesday, November 06, 2007 2:56 PM
  • Mark, I would use either

     

    e.Font.SizeInPoints or

    e.Font.Size (I think the latter is better)

     

    to calculate the true size of the string. You just multiply the width of the font by the number of characters including blank spaces in your e.ToolTipText. Of course you will have to either .Split( .... ) it or use Regex to find what is inside.

     

    You can get this info on OnDraw event.

    Tuesday, November 06, 2007 3:19 PM
  • Maybe I could do what you suggested; multiplying the width of the font by the number of characters PER LINE and maintain the maximum value. Afterwards I could determine how many lines I have and multiply that by the height of the font. After knowing the maximum width and height I could set the bounds of the tooltip. But hold on, the API MeasureString does this all for me, so why bother.

     

    Also, I cannot reassign the bounds of the tooltip in OnDraw. I tried this but somehow the base class still uses the original dimensions. Therefore, I have to assign the new bounds in OnPopup to ensure that the base class adopts these new dimensions when drawing the tooltip.

     

    Wednesday, November 07, 2007 9:03 AM
  •  MarkyMark unique attempt#5847 wrote:

    Maybe I could do what you suggested; multiplying the width of the font by the number of characters PER LINE and maintain the maximum value. Afterwards I could determine how many lines I have and multiply that by the height of the font. After knowing the maximum width and height I could set the bounds of the tooltip. But hold on, the API MeasureString does this all for me, so why bother.

     

    Also, I cannot reassign the bounds of the tooltip in OnDraw. I tried this but somehow the base class still uses the original dimensions. Therefore, I have to assign the new bounds in OnPopup to ensure that the base class adopts these new dimensions when drawing the tooltip.

     

     

    Well Mark, you havent't wasted your time! You developed a cute solution for sure. I've already incorporated your code in my MyTooltip. As far as a dream of being a truck driver you are not alone. Janet Reno, former Attorney General once said answering a reporter's question: "What are you going to do after your term expires?" - Drive a truck across the country.

     

    I see a slight imperfection in your code handling my typically two-line tooltips. The right edge cuts the last letter uncomfortably too close.

     

    Thanks.

    Wednesday, November 07, 2007 1:18 PM
  • Alex, I have no problems displaying a tooltip of 2 lines using Font("Arial", 11). Could you post the font used and the text that you are displaying in the tooltip. I can have a look at it.

     

    Besides this, I still have the following issues:

    1) reposition the tooltip when it is about to be displayed partly off screen to ensure that it's fully on screen (I have a feeling that I might have to use e.AssociatedWindow to tackle this) 

    2) investigate why I cannot use tooltip enhancements like balloon, icon, caption, etc. (but this is a nice-to-have issue)

    Wednesday, November 07, 2007 3:09 PM
  • Alex, I didn't have any problem displaying a tooltip of 2 lines using Font("Arial", 11). Could you post the font you used as well as the text for the tooltip then I will look into this. Could you also tell me the type of Control that is associated with the tooltip.

     

    Besides this, I still have the following issues:

    1) reposition the tooltip when it is about to be positioned partly off screen

    2) investigate how tooltip enhancements can be used like balloon, icon, caption, etc. (but this is a nice-to-have issue)

     

    Wednesday, November 07, 2007 5:22 PM
  •  MarkyMark unique attempt#5847 wrote:

    Alex, I have no problems displaying a tooltip of 2 lines using Font("Arial", 11). Could you post the font used and the text that you are displaying in the tooltip. I can have a look at it.

     

    Besides this, I still have the following issues:

    1) reposition the tooltip when it is about to be displayed partly off screen to ensure that it's fully on screen (I have a feeling that I might have to use e.AssociatedWindow to tackle this) 

    2) investigate why I cannot use tooltip enhancements like balloon, icon, caption, etc. (but this is a nice-to-have issue)

     

    Hi Mark,

     

    You are doing a great job. A lot of people may benefit. I like your program. Unfortunately, I cannot help you either with theoretical knowledge or participation. For me it is a sort of a secondary issue. It is already very nice to have what I've got. A big step from the bleak appearance of the standard tooltip.

     

    Unswering your question. I perhaps distracted your attention with two-decker MyTooltip. Being two story is not the issue. Most of my tooltips are this way and if you want me to examine if this will appear in a simple one-line text, I will do it but I will have to either change the code or find a sample.

     

    The thing is that the computed width falls short of the actual length of the string. It is nice that the control takes for the width the longest of two lines. It is smart. Take a look at one of my examples:

     

    this.MyToolTip1.SetToolTip ( this.pushSaveDualMisSpell, "WILL SAVE A PAIR OF MISSPELLED WORDS in Rtf and \r\n" +

    "CORRECT pair of WORDS from TextBox To The LEFT in DualMisTyped Table     " );

     

    If the double quote follows the last word "Table" immediately, the word will have the last letter cut off and the text looks uncomfortably circumcised. You feel something is missing. You feel, perhaps there is another word beyond the edge or something. Thus I still have to pad it with a few blanks. It is still a big improvement as to what I had before you improved it. Just a few blanks are needed.

     

    Thanks.

    Monday, November 12, 2007 9:20 PM
  • Hi Alex,

     

    Weird, but I cannot reproduce the problem you are having. The tooltip shows the two lines completely, even when I trim the additional spaces of your example. Looking at the name you provided, I guess that the control that is associated with the tooltip is a button. Although I use a panel, this has no influence on the appearance of the tooltip. Last but not least, maybe the font you are using could be the reason why some lines are not shown completely. Otherwise I don't have a clue.

     

    Mark

     

     

    Tuesday, November 13, 2007 7:08 AM
  •  MarkyMark unique attempt#5847 wrote:

    Hi Alex,

     

    Weird, but I cannot reproduce the problem you are having. The tooltip shows the two lines completely, even when I trim the additional spaces of your example. Looking at the name you provided, I guess that the control that is associated with the tooltip is a button. Although I use a panel, this has no influence on the appearance of the tooltip. Last but not least, maybe the font you are using could be the reason why some lines are not shown completely. Otherwise I don't have a clue.

     

    Mark

     

     

     

    Mark, you are right, the control is a button. It is mnemonic to assign a prefix to controls: "push" for buttons, "txt" for textBox, "rtf" for richTextBox, etc.

     

    The font must be "ariel" If not, I will come back and correct it.

     

    The problem is so minor it is not worth pursuing.

     

    I see the same thing in one line tooltips.

     

    Thanks.

    Tuesday, November 13, 2007 10:15 PM