How to display abbreviated path names in .NET
.net, filenames, path
Solution
Display Abbreviated Paths using `TextRenderer`.`MeasureText`
I had the same dilemma as the OP in that I needed a solution for showing an abbreviated path without too much hassle so that my UI could easily show the main parts of a path. The final solution: Use `TextRenderer`'s `MeasureText` method like so:
public static string GetCompactedString(
string stringToCompact, Font font, int maxWidth)
{
// Copy the string passed in since this string will be
// modified in the TextRenderer's MeasureText method
string compactedString = string.Copy(stringToCompact);
var maxSize = new Size(maxWidth, 0);
var formattingOptions = TextFormatFlags.PathEllipsis
| TextFormatFlags.ModifyString;
TextRenderer.MeasureText(compactedString, font, maxSize, formattingOptions);
return compactedString;
}
Important: Passing in a formatting option of `TextFormatFlags.ModifyString` actually causes the `MeasureText` method to alter the string argument (`compactedString`) to be a compacted string. This seems very weird since no explicit `ref` or `out` method parameter keyword is specified and strings are immutable. However, its definitely the case. I assume the string's pointer was updated via unsafe code to the new compacted string.
As another lessor note, since I want the compacted string to compact a path, I also used the `TextFormatFlags.PathEllipsis` formatting option.
I found it handy to make a small extension method on control so that any control (like TextBox's and Label's) can set their text to a compacted path:
public static void SetTextAsCompactedPath(this Control control, string path)
{
control.Text = GetCompactedString(path, control.Font, control.Width);
}
Alternative Ways to Compact a Path:
There are home grown solutions to compact paths as well as some WinApi calls one can use.
PathCompactPathEx - Compacting a String Based on Desired String Length in Characters
You can use pinvoke to call `PathCompactPathEx` to compact a string based on the number of characters you wish to restrict it to. Note that this does not take into account font and how wide the string will appear on a screen.
Code Source PInvoke: http://www.pinvoke.net/default.aspx/shlwapi.pathcompactpathex
[DllImport("shlwapi.dll", CharSet=CharSet.Auto)]
static extern bool PathCompactPathEx(
[Out] StringBuilder pszOut, string szPath, int cchMax, int dwFlags);
public static string CompactPath(string longPathName, int wantedLength)
{
// NOTE: You need to create the builder with the
// required capacity before calling function.
// See http://msdn.microsoft.com/en-us/library/aa446536.aspx
StringBuilder sb = new StringBuilder(wantedLength + 1);
PathCompactPathEx(sb, longPathName, wantedLength + 1, 0);
return sb.ToString();
}
Other Solutions
There are more solutions out there as well that involve regular expressions and smart parsing of paths to determine where to put ellipsis. These are a few I saw:
- Coding Horror: - Shortening Long File Paths
- CodeProject: - Auto Ellipsis
Problem
I have a fixed-length field I'd like to display path information in. I thought in .NET there is a method that will abbreviate long path names to fit in fixed length fields by inserting ellipsis, for example "......\myfile.txt". I can't for the life of me find this method.