سؤال

I am creating a control in WPF that shows units using a System.Windows.Control.RichTextBox.

The problem is the RichTextBox control shows a plain text instead of a formatted text. I guess the RichTextBox control has a bug and I don't know how to do it, because it works depending on the computer.

The XAML code is,

<RichTextBox x:FieldModifier="private"
             x:Name="TxtItem1"
             IsReadOnly="True"
             IsHitTestVisible="False"
             HorizontalContentAlignment="Center"
             VerticalContentAlignment="Center" />

And part of the code behind is:

private static void UpdateDocument(RichTextBox control, DependencyPropertyChangedEventArgs e)
{
    string content = e.NewValue as string;
    control.Document = content.Html1ToFlowDocument();
}

The function Html1ToFlowDocument converts a string into a FlowDocument. The following image is in a computer that the code goes fine (Windows 7 64 bits):

GOES

And the next one does not work (Windows 7 64 bits):

WRONG

Another approach was using a RTF text but I have the problem.

The code of the function Html1ToFlowDocument,

public static class Html1ToDocument
{
    public static FlowDocument Html1ToFlowDocument(this string text)
    {
        var mcFlowDoc = new FlowDocument();

        XmlDocument doc = new XmlDocument();
        doc.LoadXml(string.Format("<P>{0}</P>", text));

        XmlElement root = doc.GetElementsByTagName("P")[0] as XmlElement;

        IEnumerable<Inline> children;
        try
        {
            children = ParseChildren(root);
        }
        catch (Exception ex)
        {
            throw new FormatException("Unsupported text.", ex);
        }

        var paragraph = new Paragraph();
        paragraph.Inlines.AddRange(children);

        mcFlowDoc.Blocks.Add(paragraph);
        return mcFlowDoc;
    }

    private static IEnumerable<Inline> ParseChildren(XmlElement root)
    {
        Span sitem;
        List<Inline> children;

        foreach (XmlNode element in root.ChildNodes)
        {
            Inline item = null;
            if (element is XmlElement)
            {
                XmlElement xelement = (XmlElement)element;
                switch (xelement.Name.ToUpper())
                {
                    case "SUB":
                        children = ParseChildren(xelement).ToList();
                        if (children.Count == 1 && children.First() is Run)
                        {
                            item = children.First();
                            item.Typography.Variants = FontVariants.Subscript;
                        }
                        else
                        {
                            sitem = new Span();
                            sitem.Typography.Variants = FontVariants.Subscript;
                            sitem.Inlines.AddRange(children);
                            item = sitem;
                        }

                        break;
                    case "SUPER":
                        children = ParseChildren(xelement).ToList();
                        if (children.Count == 1 && children.First() is Run)
                        {
                            item = children.First();
                            item.Typography.Variants = FontVariants.Superscript;
                        }
                        else
                        {
                            sitem = new Span();
                            sitem.Typography.Variants = FontVariants.Superscript;
                            sitem.Inlines.AddRange(children);
                            item = sitem;
                        }
                        break;
                }

                yield return item;
            }
            else if (element is XmlText)
            {
                item = new Run(element.InnerText);
                yield return item;
            }
        }
    }
}
هل كانت مفيدة؟

المحلول 2

I have used a tricky solution. The characters of the controls in WPF are based on the Unicode Standard 6.3 and there is a table in this standard with special characters, specifically subscript and superscript. And the most amazing is that it works in a simple TextBox.

⁰ i ⁴ ⁵ ⁶ ⁷ ⁸ ⁹ ⁺ ⁻ ⁼ ⁽ ⁾ ⁿ ₀ ₁ ₂ ₃ ₄ ₅ ₆ ₇ ₈ ₉ ₊ ₋ ₌ ₍ ₎ ₐ ₑ ₒ ₓ ₔ

You can download the specification here: http://www.unicode.org/charts/PDF/U2070.pdf

And there are more special characters here: http://www.unicode.org/charts/

TextBox example

نصائح أخرى

If most things on the surface between the two computers seem the same (i.e. OS version, locale, framework installed) then I'd wager it's an issue with fonts. You're essentially getting the same text in both cases, but you're hitting a wall with superscripts and subscripts. A quick little googling showed me that other people are having similar problems:

Looks like the font in question needs to be:

  • Open Type
  • Have both superscript and subscript variants

Here's some information on checking for fonts: Detect whether a font supports variants (like superscript and subscript)

My recommendation might be to try out a different font to see if it fixes it, and if so, find out how you can ensure you'll get the fonts you need on both (meaning, all that you intend to deploy to) machines.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top