Just a while ago, I’ve implemented a label control with a text trim behavior. If the text is longer than the available size of the label the text is truncated like this: “Text is too lo…”
Brad Cunningham and Robby Ingebretsen did a similar implementation. Both trimming the text during the measure/arrange call.
The implementation of my trimming functionality is similar to the solutions of Brad or Robby. Additionally, I’ve implemented a calculator class to get the text-width with an integrated cache. This makes the trimming function very fast.
As I saw the great examples of Brad and Robby, I decided to share my code too.
You can find the source code and a live example here:
Please note: the source code is an extract of another project and I did not change the namespace.
Here are some main decisions for the label control:
- It derived from Control, because one should not be able to add a child control to it (just like the normal TextBlock control)
- The template is hardcoded, because nobody should be able to change it.
- The text trimming functionality is implemented in the MeasureOverride method, because it’s the only place I get the available space from the parent element (including infinity)
- Each char-width of the text is calculated and cached until the text or some font property changes. This makes the calculation very fast.
- The class FontDefinitions provides an optimized char-width calculator with an integrated cache.
- The class FontDefinitions uses a TextBlock to retrieve the text length, because a TextBlock immediately returns the width via the property ActualWidth (without any layout cycle).
- The memory consumption of the font width cache is very small.
