Search code examples
.netcolorslabelhighlighting

Highlighting multiple characters in a text label


I'm searching for a way to highlight multiple characters in a text label using the .NET Compact Framework. E.g. in a label which contains the text Hello World, i want the H and the r highlighted like in this example:

Hello World

My initial solution was to misuse & to underline the target characters, but unfortunately it will only underline one character. I don't care if the characters are in a different color, bold or underlined, the only important thing is that they stand out.


Solution

  • Preview:

    Preview

    Updates:

    Added color highlighting support.

    Code:

    Tested on .NET Compact Framework 3.5, Windows Mobile 6 SDK, should probably work on the .NET framework too.

    /// <summary>
    /// A label which offers you the possibility to highlight characters 
    /// at defined positions.
    /// See <see cref="HighlightPositions"/>, <see cref="HighlightStyle"/> and
    /// <see cref="HighlightColor"/>
    /// The text in the Text property will be displayed.
    /// </summary>
    public partial class HighlightLabel : Control
    {
        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        public HighlightLabel()
        {
            InitializeComponent();
        }
        /// <summary>
        /// An array of all positions in the text to be highlighted.
        /// </summary>
        public int[] HighlightPositions { get; set; }
    
        /// <summary>
        /// Gets or sets the highlight style.
        /// </summary>
        public FontStyle HighlightStyle { get; set; }
    
        /// <summary>
        /// Gets or sets the highlight color.
        /// </summary>
        public Color HighlightColor { get; set; }
    
        // Paints the string and applies the highlighting style.
        protected override void OnPaint(PaintEventArgs e)
        {
            if (HighlightPositions == null)
                HighlightPositions = new int[] { };
    
            var usedOffsets = new List<float>();
    
            for (var i = 0; i < Text.Length; i++)
            {
                var characterToPaint =
                    Text[i].ToString(CultureInfo.CurrentCulture);
    
                var selectedFont = Font;
                var selectedColor = ForeColor;
    
                if (HighlightPositions.Contains(i))
                {
                    selectedColor = HighlightColor;
                    selectedFont = new Font(Font.Name, Font.Size, 
                        HighlightStyle);
                }
    
                var currentOffset = usedOffsets.Sum();
    
                e.Graphics.DrawString(characterToPaint, selectedFont,
                    new SolidBrush(selectedColor),
                    new RectangleF(e.ClipRectangle.X + currentOffset,
                        e.ClipRectangle.Y, e.ClipRectangle.Width,
                        e.ClipRectangle.Height));
    
                var offset = e.Graphics.MeasureString(characterToPaint,
                    selectedFont).Width;
    
                usedOffsets.Add(offset);
            }
        }
    }
    

    Usage:

    highlightLabel.HighlightPositions = new[] { 1, 8 };
    highlightLabel.HighlightStyle = FontStyle.Bold;
    highlightLabel.HighlightColor = Color.Red