there lot of questions (eg: 1, 2, 3, 4, 5) asking how can truncate string desired amount of characters. want piece of text truncated fit in container. (ie: crop string it's width in pixels, not characters).
this easy if use wpf, not in winforms...
so: how can truncate string make fit in container?
after day of coding found solution , wanted share community.
first of all: there no native truncate function string or winforms textbox. if use label, can use autoellipsis property.
fyi: ellipsis punctuation mark consist of 3 dots. ie: …
that's why made this:
public static class extensions { /// <summary> /// truncates textbox.text property fit in textbox. /// </summary> static public void truncate(this textbox textbox) { //determine direction of truncation bool direction = false; if (textbox.textalign == horizontalalignment.right) direction = true; //get text string truncatedtext = textbox.text; //truncate text truncatedtext = truncatedtext.truncate(textbox.font, textbox.width, direction); //if text truncated if (truncatedtext != textbox.text) { //set textbox text textbox.text = truncatedtext; //after setting text, cursor position changes. here set location of cursor manually. //first determine position, default value applies direction = left. //this position when cursor needs behind last char. (example:"…my text|"); int position = 0; //if truncation direction right position should before ellipsis if (!direction) { //this position when cursor needs before last char (which ellipsis). (example:"my text|…"); position = 1; } //set cursor position textbox.select(textbox.text.length - position, 0); } } /// <summary> /// truncates string smaller desired width. /// </summary> /// <param name="font">the font used determine size of string.</param> /// <param name="width">the maximum size string should after truncating.</param> /// <param name="direction">the direction of truncation. true left (…ext), false right(tex…).</param> static public string truncate(this string text, font font, int width, bool direction) { string truncatedtext, returntext; int charindex = 0; bool truncated = false; //when user typing , truncation happens in textchanged event, typed text lost. //example: imagine string "hello worl" truncate if add 'd'. depending on font output //could be: "hello wor…" (notice 'l' missing). undesired effect. //to prevent happening ellipsis included in initial sizecheck. //at point, direction not important place ellipsis behind text. truncatedtext = text + "…"; //get size of string in pixels. sizef size = measurestring(truncatedtext, font); //do while string bigger desired width. while (size.width > width) { //go next char charindex++; //if character index larger or equal length of text, truncation unachievable. if (charindex >= text.length) { //truncation unachievable! //throw exception user knows what's going on. throw new indexoutofrangeexception("the desired width of string small truncate to."); } else { //truncation still applicable! //raise flag, indicating text truncated. truncated = true; //check way text should truncated to, remove 1 char , add ellipsis. if (direction) { //truncate left. add ellipsis , remove left. truncatedtext = "…" + text.substring(charindex); } else { //truncate right. remove right , add ellipsis. truncatedtext = text.substring(0, text.length - charindex) + "…"; } //measure string again. size = measurestring(truncatedtext, font); } } //if text got truncated, change return value truncated text. if (truncated) returntext = truncatedtext; else returntext = text; //return desired text. return returntext; } /// <summary> /// measures size of string object. /// </summary> /// <param name="text">the string measured.</param> /// <param name="font">the font used measure size of string.</param> /// <returns>a sizef object containing height , size of string.</returns> static private sizef measurestring(string text, font font) { //to measure string use graphics.measurestring function, method can called painteventargs instance. //to call constructor of painteventargs class, must pass graphics object. we'll use picturebox object achieve this. picturebox pb = new picturebox(); //create painteventargs correct parameters. painteventargs pea = new painteventargs(pb.creategraphics(), new system.drawing.rectangle()); pea.graphics.pageunit = graphicsunit.pixel; pea.graphics.pagescale = 1; //call measurestring method. methods calculates height , width of string be, given specified font. sizef size = pea.graphics.measurestring(text, font); //return sizef object. return size; } }
usage: class can copy , paste in namespace contains winforms form. make sure include "using system.drawing;"
this class has 2 extensions methods, both called truncate. can this:
public void textbox1_textchanged(object sender, eventargs e) { textbox1.truncate(); }
you can type in textbox1 , if needed, automatically truncate string fit in textbox , add ellipsis.
overview: class contains 3 methods:
- truncate (extension textbox)
- truncate (extension string)
- measurestring
truncate (extension textbox)
this method automatically truncates textbox.text property. direction of truncation determent textalign property. (eg: "truncation left alignm…", "…ncation right alignment".) please note: method might need altering work other writing systems such hebrew or arabic.
truncate (extension string)
in order use method must pass 2 parameters: font , desired width. font used calculate width of string , desired width used maximum width allowed after truncation.
measurestring
this method private in code snippet. if want use it, must change public first. method used measure height , width of string in pixels. requires 2 parameters: text measured , font of text.
i hope helped this. perhaps there other way this, found this answer hans passant, truncates tooltipstatuslabel, quite impressive. .net skills near of hans passant haven't managed convert code work textbox... if did succeeed, or have solution love see it! :)
Comments
Post a Comment