Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. TextRenderer.DrawText with TextFormatFlags.ModifyString

TextRenderer.DrawText with TextFormatFlags.ModifyString

Scheduled Pinned Locked Moved C#
graphicshelpquestionannouncement
3 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    Lea Hayes
    wrote on last edited by
    #1

    Hi all! I am creating a simple user control which renders text within its paint event handler. Under some circumstances (when the output rectangle is very small) the exception "The object is already in use elsewhere." occurs...Which does not make any sense because a) the program is not multithreaded and b) it isn't particuarly complex. This crashing began when I started using the TextFormatFlags.ModifyString flag, and the problem is likewise immediately cured by removing this flag. Am I using the flag in an incorrect fashion? The itemLabel string is actually updated correctly (end ellipsis is added when displayed).

    // Force duplication of string, the original value is changed otherwise.
    string itemLabel = new string(item.Label.ToCharArray());

    // Use text renderer to output required text.
    TextRenderer.DrawText(ctx.Graphics, itemLabel, activeFont, Rectangle.Round(extraLabelBounds), textColour, backgroundColor, TextFormatFlags.EndEllipsis | TextFormatFlags.ModifyString);

    If this is a problem, is it possible to get the EndEllipsis version of the string based upon the graphics context, font, output rectangle bounds, and text? Many thanks! Lea Hayes

    G 1 Reply Last reply
    0
    • L Lea Hayes

      Hi all! I am creating a simple user control which renders text within its paint event handler. Under some circumstances (when the output rectangle is very small) the exception "The object is already in use elsewhere." occurs...Which does not make any sense because a) the program is not multithreaded and b) it isn't particuarly complex. This crashing began when I started using the TextFormatFlags.ModifyString flag, and the problem is likewise immediately cured by removing this flag. Am I using the flag in an incorrect fashion? The itemLabel string is actually updated correctly (end ellipsis is added when displayed).

      // Force duplication of string, the original value is changed otherwise.
      string itemLabel = new string(item.Label.ToCharArray());

      // Use text renderer to output required text.
      TextRenderer.DrawText(ctx.Graphics, itemLabel, activeFont, Rectangle.Round(extraLabelBounds), textColour, backgroundColor, TextFormatFlags.EndEllipsis | TextFormatFlags.ModifyString);

      If this is a problem, is it possible to get the EndEllipsis version of the string based upon the graphics context, font, output rectangle bounds, and text? Many thanks! Lea Hayes

      G Offline
      G Offline
      Guffa
      wrote on last edited by
      #2

      What is the class of the exception that you are getting? That might help to determine what it is that is used elsewhere... Where do you get the Graphics and Font objects from?

      Despite everything, the person most likely to be fooling you next is yourself.

      L 1 Reply Last reply
      0
      • G Guffa

        What is the class of the exception that you are getting? That might help to determine what it is that is used elsewhere... Where do you get the Graphics and Font objects from?

        Despite everything, the person most likely to be fooling you next is yourself.

        L Offline
        L Offline
        Lea Hayes
        wrote on last edited by
        #3

        Hi, The exception class is System.InvalidOperationException. The Graphics class is as provided by the paint event handler (this is the overriden method protected override void OnPaint(PaintEventArgs e)). The font object is generated by:

        Font activeFont = SystemFonts.DefaultFont;
        if(series of conditions)
        activeFont = new Font(activeFont, FontStyle.Bold);

        Here is the exception information: System.InvalidOperationException was unhandled Message="Object is currently in use elsewhere." Source="System.Drawing" StackTrace: at System.Drawing.Graphics.CheckErrorStatus(Int32 status) at System.Drawing.Graphics.DrawLine(Pen pen, Single x1, Single y1, Single x2, Single y2) Whilst the above suggests that the problem is related to the 'DrawLine' method, just simply removing the 'TextFormatFlags.ModifyString' flag prevents the crash from occurring. For my particular application all I needed was a boolean value which indicates whether the output text was truncated or not. Whilst I have found a workaround for this (listed below), I am still interested to find out why this exception is being thrown...I have double-checked my code and I cannot understand how the objects are being used elsewhere because they are pretty much created each time the paint event is handled. The only things which are in common are the data item and the user control itself.

        // Use text renderer to output required text.
        if (extraLabelBounds.Width > 0)
        TextRenderer.DrawText(ctx.Graphics, itemLabel, activeFont, Rectangle.Round(extraLabelBounds), textColour, backgroundColor, TextFormatFlags.EndEllipsis);

        // NOTE: Unfortunately the following is probably less efficient than with the alternative flag...

        // Measure string both with and without end ellipsis to determine if string has overflown or not.
        Size measuredA = TextRenderer.MeasureText(ctx.Graphics, itemLabel, activeFont);
        Size measuredB = TextRenderer.MeasureText(ctx.Graphics, itemLabel, activeFont, Size.Round(extraLabelBounds.Size), TextFormatFlags.EndEllipsis);

        // If label rendered label length is different to the actual item label then a
        // tooltip will be made available.
        bool hasOverflown = !measuredA.Equals(measuredB);

        Thanks, Lea Hayes

        1 Reply Last reply
        0
        Reply
        • Reply as topic
        Log in to reply
        • Oldest to Newest
        • Newest to Oldest
        • Most Votes


        • Login

        • Don't have an account? Register

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • World
        • Users
        • Groups