Feedback

C# - Apps: BBCode in RichTextBlock binden

Veröffentlicht von am 4/12/2015
(0 Bewertungen)
Diese angefügte Eigenschaft kann spezielle Formatierungen in Form von BBCode in einem RichTextBlock anzeigen. Das anzeigen kann dabei auch über eine Bindung geschehen

Meine Implementierung kann Text Fett [ b ], Kursiv [ i ] oder eingefärbt [ Color=Farbe ] anzeigen. (Jeweils ohne den extra Leerzeichen in den eckigen Klammern.) Beendet wird die jeweilige Formatierung mit [/TagName]. Auch das Erstellen von Paragrafen mittels [p]...[/p] ist möglich.

Beispiel String
[p]Paragraf 1[/p][p][b ]Fett [i]Fett & Kursiv[/b] Kursiv[/i][/p][p][color=red]Rot[/color] [color=green]Grün[/color] [color=#F09]RGB-Farbe: Magenta[/color][/p]
Hinweis: Leerzeichen hinter [b muss entfernt werden

Benötigte 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
/// <summary>
/// Stellt Möglichkiten bereit um BBCode in einem <see cref="Windows.UI.Xaml.Controls.RichTextBlock"/> anzuzeigen.
/// </summary>
public class RichTextBlockBBCode
{
    /// <summary>
    /// Ruft den per <see cref="SetBBCode"/> gesetzten BBCode ab.
    /// </summary>
    /// <param name="rtb">Der <see cref="Windows.UI.Xaml.Controls.RichTextBlock"/> dessen BBCode abgerufen werden soll.</param>
    /// <returns>Der gesetzte BBCode des angegebenen Controls.</returns>
    public static string GetBBCode(RichTextBlock rtb)
    {
        return (string)rtb.GetValue(BBCodeProperty);
    }

    /// <summary>
    /// Setzt BBCode zum Anzeigen in einem <see cref="Windows.UI.Xaml.Controls.RichTextBlock"/>.
    /// </summary>
    /// <param name="rtb">Der <see cref="Windows.UI.Xaml.Controls.RichTextBlock"/>, für den der BBCode gesetzt werden soll.</param>
    /// <param name="bbcode">Der zu setzende BBCode.</param>
    public static void SetBBCode(RichTextBlock rtb, string bbcode)
    {
        rtb.SetValue(BBCodeProperty, bbcode);
    }

    /// <summary>
    /// Stellt die angefügte BBCode-Abhängigkeitseigenschaft dar.
    /// </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);
    }
}

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!