C# - Apps: bind RichTextBlock to BBCode

By , 4/12/2015
(0 ratings)
This class provides an attached property for RichTextBlock. It is possible to assign a string with BBCode to this property to show them formatted in the Control.

The following BBCode tags are supported:
- [b ] (without space after the ‘b’) = bold formatted
- [i] = italic formatted
- [color=name] = prints the text in the color ‘name’. Common English color names like “red” or “blue” supported, but also RGB code like “#FF0090”.

Example String
[p]Paragraph 1[/p][p][b ]bold [i]bold & italic[/b] italic[/i][/p][p][color=red]red[/color] [color=green]green[/color] [color=#F09]RGB color: magenta[/color][/p]
Hinweis: The space after [b must be removed

Required Namespaces
System
System.Collections.Generic
Windows.UI
Windows.UI.Text
Windows.UI.Xaml
Windows.UI.Xaml.Controls
Windows.UI.Xaml.Documents
Windows.UI.Xaml.Markup
Windows.UI.Xaml.Media
System.Linq
Translate to VB
/// <summary>
/// Provides the opportunity to set a BBCode in a <see cref="Windows.UI.Xaml.Controls.RichTextBlock"/>.
/// </summary>
public class RichTextBlockBBCode
{
    /// <summary>
    /// Gets the BBCode which was setted with the <see cref="SetBBCode"/> method.
    /// </summary>
    public static string GetBBCode(RichTextBlock rtb)
    {
        return (string)rtb.GetValue(BBCodeProperty);
    }

    /// <summary>
    /// Sets the BBCode to show it a <see cref="Windows.UI.Xaml.Controls.RichTextBlock"/>.
    /// </summary>
    /// <param name="rtb">The <see cref="Windows.UI.Xaml.Controls.RichTextBlock"/>, which should dispaly the formatted string.</param>
    /// <param name="bbcode">The BBCode to set.</param>
    public static void SetBBCode(RichTextBlock rtb, string bbcode)
    {
        rtb.SetValue(BBCodeProperty, bbcode);
    }

    /// <summary>
    /// Represents the attached BBCode dependency property.
    /// </summary>
    public static readonly DependencyProperty BBCodeProperty = DependencyProperty.RegisterAttached("BBCode", typeof(string), typeof(RichTextBlockBBCode), new PropertyMetadata(string.Empty, OnBBCodeChanged));

    private static void OnBBCodeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var rtb = d as RichTextBlock;
        var bcc = e.NewValue as string;

        rtb.Blocks.Clear();

        foreach (var item in bcc.Split(new string[] { "[p]", "[/p]" }, StringSplitOptions.RemoveEmptyEntries))
        {
            var p = new Paragraph();

            var formats = new List<string>();
            foreach (var s in SplitInBBCodeTags(item.ToCharArray()))
            {
                if (s.Length > 0 && s[0] == '[')
                {
                    if (s.Length > 2 && s[1] == '/')
                    {
                        var n = formats.FirstOrDefault(x => x == "[" + s.Substring(2) || x.StartsWith("[" + s.Substring(2, s.Length - 3) + "="));
                        if (n != null)
                            formats.Remove(n);
                    }
                    else
                    {
                        formats.Add(s);
                    }
                }
                else
                {
                    var run = CreateRun(formats);
                    run.Text = s;
                    p.Inlines.Add(run);
                }
            }

            rtb.Blocks.Add(p);
        }
    }

    static Run CreateRun(IEnumerable<string> formats)
    {
        var run = new Run();
        foreach (var format in formats)
        {
            switch (format)
            {
                case "[b]":
                    run.FontWeight = FontWeights.Bold;
                    break;
                case "[i]":
                    run.FontStyle = FontStyle.Italic;
                    break;
                default:
                    if (format.StartsWith("[color="))
                    {
                        try
                        {
                            var color = StringToColor(format.Substring(7, format.Length - 8));
                            run.Foreground = new SolidColorBrush(color);
                        }
                        catch { }
                    }
                    break;
            }
        }
        return run;
    }

    static Color StringToColor(string colorName)
    {
        string xaml = "<Color xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' >" + colorName + "</Color>";
        return (Color)XamlReader.Load(xaml);
    }

    static IEnumerable<string> SplitInBBCodeTags(char[] s)
    {
        int start = 0;
        for (int i = 1; i < s.Length; ++i)
        {
            if (s[i] == '[')
            {
                yield return new string(s, start, i - start);
                start = i;
            }
            if (s[i] == ']')
            {
                yield return new string(s, start, i - start + 1);
                start = i + 1;
            }
        }
        yield return new string(s, start, s.Length - start);
    }
}

Comments

 

Log in, to comment!