Replacing part of a string only if wider

Hi there,

My question is how to replace a part of a string only if it's wider than its container (Label). I want to do it for displaying status messages just like status messages of setup apps:

[installing c:\test\test.exe                              ]
[installing c:\test\path\bin\..........\another.exe]

I hope that I could explain my question clearly.

Who is Participating?
Mike TomlinsonConnect With a Mentor Middle School Assistant TeacherCommented:
I would use a PictureBox to display your file.  Then you can use the Graphics.DrawString() method and specify the StringTrimming.EllipsisPath flag in the StringFormat for your drawn text:

        private void Form1_Load(object sender, EventArgs e)
            UpdateFile(@"C:\Documents and Settings\Michael\My Documents\someFile.txt");

        private void Form1_Resize(object sender, EventArgs e)

        private void UpdateFile(String file)
            pictureBox1.Tag = "[ Installing " + file + " ]";

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
            if (pictureBox1.Tag != null)
                SizeF textSize = e.Graphics.MeasureString((String)pictureBox1.Tag, this.Font);
                StringFormat sf = new StringFormat(StringFormatFlags.NoWrap);
                sf.Trimming = StringTrimming.EllipsisPath;
                e.Graphics.DrawString((String)pictureBox1.Tag, this.Font, Brushes.Black, new RectangleF(new PointF(0, pictureBox1.Height / 2 - textSize.Height / 2), new SizeF(pictureBox1.Width, textSize.Height)), sf);

you can use the folowing code block to achive what you want.

Dim str, str1 As String
        Dim int1, maxlength As Integer
        maxlength = 35 ' Assume that the label can take 35 charecters
        str = TextBox1.Text  'assume the path is stored in str
        If str.Length > maxlength Then  ' let us compare and see if its length is greater than max length
            int1 = str.Length - str.LastIndexOf("\") ' Get the length of the string from the last "\"
            str1 = str.Substring(str.LastIndexOf("\"), int1) ' get that string into a temp variable
            str1 = str1.PadLeft(int1 + 5, ".") ' Padd the ... to the string
            str = str.Substring(0, maxlength - int1 - 5) + str1 ' Add the first part of the string to newly formed string
        End If

str now has the string in the format you want.

bmbsaAuthor Commented:
Both solutions won't acheive what I want, I wrote some code that works as expected.

thanks alot
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

Mike TomlinsonMiddle School Assistant TeacherCommented:
What is it that my code is not achieving?  It worked just as you described in my test...

Also, please show us the code that you are happy with.  =)
bmbsaAuthor Commented:
Here is my code, compare it with yours

            string status, find;
            Graphics g = this.CreateGraphics();
            SizeF stringSize = new SizeF();
            int textWidth, ctrlWidth, count=0, plus=0;

            foreach (File f in Files)
                status = "Checking " + f.FullName;
                stringSize = g.MeasureString(status, label1.Font);
                textWidth = (int)stringSize.Width;
                ctrlWidth = toolStripStatusLabel1.Width;
                while (textWidth > ctrlWidth)
                    plus = (count == 0) ? 2 : 0;
                    int bSlash1=subDir.FullName.IndexOf("\\", count+plus)+1;
                    int bSlash2 = subDir.FullName.IndexOf("\\", bSlash1);
                    find = subDir.FullName.Substring(bSlash1, bSlash2 - bSlash1);
                    status = status.Replace(find, "...");
                    textWidth = (int)g.MeasureString(status, label1.Font).Width;
                    count += bSlash2;

Mike TomlinsonMiddle School Assistant TeacherCommented:
With regards to your comment:

    "I wrote some code that works as expected."

You need to more detailed in your problem description if you want results that specific...

You only said:

    "My question is how to replace a part of a string only if it's wider than its container (Label). "

And my code does just that.  It replaces part of the drawn string with "..." based on the width of its container (a picturebox in my example).


Your code has a flaw in it.  If there are nested directories where the same folder name appears more than once in the heirarchy then this line mayl chop out more than you expected:

    status = status.Replace(find, "...");

As in:


If you were replacing the "a" part then you would get multiple ellipsis "..." in the string, possibly erasing the part you actually wanted to keep.

idle mind, good point;)
but why using a picturebox instead of a labels graphics object?
i would recommend using your function with the label itself.
Mike TomlinsonMiddle School Assistant TeacherCommented:
I don't use a Label because we aren't going to allow the Label to draw its text by itself.  The Label allows you to set the TextAlign() property but the code does not take that into account.  So I use a PictureBox so you don't have expectations about what the text will look like.  I suppose it doesn't matter to much in the end.  You could always derive your own control from either or make a UserControl to do it.
yes but by using a label instead of a textbox would give you better formatting options if you draw your text with teh given formats like TextAlign etc.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.