TextBlock 的 Wpf 本地化动态下标

Wpf localization dynamic Subscript for TextBlock

我正在使用 MVVM 模式将文本绑定到 TextBlock。 文本在数据库中定义,带有 <Subscript> 标记以定义文本何时为下标。 "Some<Subscript>subscript</Subscript>text."

我试过使用 Unicode subscripts and superscripts,但字符太小,难以阅读。

我找不到执行此操作的直接方法。有什么建议吗?

当您知道有订阅标签时,您可以在 TextBlock 中使用多个 运行。

<TextBlock>
   <Run />
   <Run />
</TextBlock>

我想你不知道下标文本的确切位置,对吧?那么,为什么不分析您的输入并以编程方式创建一个新的 运行 呢?带有普通文本的 运行s 的大小不同于带有下标文本的 运行s。

如果您需要有关以编程方式添加 运行 的帮助,请查看此 Whosebug post: How to assign a Run to a text property, programmatically?

我知道这不是 MVVM 中在 ViewModel 中定义 XAML 控件的最佳方式,但这是达到更好易读性的最快方式。

使用附加属性以对 MVVM 最友好的方式解决了我的问题。 您获取文本并根据需要添加到 TextBlock Inlines。

附属性c#:

public static class TextBlockAp {
    public static readonly DependencyProperty SubscriptTextProperty = DependencyProperty.RegisterAttached(
        "SubscriptText", typeof(string), typeof(TextboxAttachedProperty), new PropertyMetadata(OnSubscriptTextPropertyChanged));

    public static string GetSubscriptText(DependencyObject obj) {
        return (string)obj.GetValue(SubscriptTextProperty);
    }

    public static void SetSubscriptText(DependencyObject obj, string value) {
        obj.SetValue(SubscriptTextProperty, value);
    }

    private static void OnSubscriptTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
        try {
            var value = e.NewValue as string;
            if (String.IsNullOrEmpty(value)) return;
            var textBlock = (TextBlock)d;

            var startTag = "<Subscript>";
            var endTag = "</Subscript>";
            var subscript = String.Empty;
            if (value.Contains(startTag) && value.Contains(endTag)) {
                int index = value.IndexOf(startTag) + startTag.Length;
                subscript = value.Substring(index, value.IndexOf(endTag) - index);
            }

            var text = value.Split(new[] { startTag }, StringSplitOptions.None);
            textBlock.Inlines.Add(text[0]);
            Run run = new Run($" {subscript}") { BaselineAlignment = BaselineAlignment.Subscript, FontSize = 9 };
            textBlock.Inlines.Add(run);
        } catch (Exception ex) {
            if (ExceptionUtilities.UiPolicyException(ex)) throw;
        }
    }
}

xaml

<TextBlock ap:TextBlockAp.SubscriptText="{Binding MyProperty}" />

它需要更多的重构才能正常工作,但这只是一个开始。