我正在使用 MVVM 模式将文本绑定到TextBlock
.文本在数据库中定义,带有<Subscript>
标记来定义文本何时为下标。 "Some<Subscript>subscript</Subscript>text."
我尝试使用 Unicode 下标和上标,但字符看起来太小,难以阅读。
我找不到直接的方法。 有什么建议吗?
当您知道存在订阅标记时,您可以在 TextBlock 中使用多个运行。
<TextBlock>
<Run />
<Run />
</TextBlock>
我想你不知道下标文本的确切位置,对吧?那么,为什么不直接分析您的输入并以编程方式创建新的 Run?使用普通文本的运行与使用下标文本的运行具有不同的大小。
如果您需要有关以编程方式添加 Run 的帮助,请查看此 StackOverflow 帖子:如何以编程方式将 Run 分配给文本属性?
我知道这不是 MVVM 中在 ViewModel 中定义 XAML 控件的最佳方式,但这是实现更好易读性的最快方法。
使用附加属性以最 MVVM 友好的方式解决了我的问题。您可以获取文本并根据需要添加到文本块内联中。
附加属性 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}" />
它需要更多的重构才能正常工作,但这是一个开始。