【问题标题】:Binding formatted text to templated TextBlock将格式化文本绑定到模板化 TextBlock
【发布时间】:2020-01-09 04:03:39
【问题描述】:

我有一个外部控件,它显示由标签和输入控件组成的布局。我的标签需要特殊格式(下标),但目前只支持直接文本。

所以我的方法是创建一个自定义的TextBlock 实现,它公开一个新的InlineContent 依赖属性,一旦设置,它就会转换内容并将其添加到实际的Inlines 集合中。

对于布局控件,我添加了一个自定义 DataTemplate,它将标签内容绑定到我的自定义文本块的 InlineContent 属性。

ExtendedTextBlock.cs:

private static void InlinesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    if (!(d is ExtendedTextBlock b)) return;

    b.Inlines.Clear();
    if (e.NewValue is InlineCollection collection)
        b.Inlines.AddRange(collection);
    if (e.NewValue is Span span)
        b.Inlines.AddRange(span.Inlines);
    if (e.NewValue is Run run)
        b.Inlines.Add(run);
    if (e.NewValue is string str)
        b.Inlines.Add(new Run(str));
}

数据模板:

<DataTemplate>
    <controls:ExtendedTextBlock InlineContent="{Binding}" />
</DataTemplate>

标签:

<dxlc:LayoutItem.Label>
    <Span>
        <Run>Right (R</Run>
        <Run Typography.Variants="Subscript">R</Run>
        <Run>)</Run>
    </Span>
</dxlc:LayoutItem.Label>

这适用于常规文本(字符串),但是当我将 Span 设置为标签的内容时,会出现以下异常:

System.Windows.Markup.XamlParseException: '集合已修改;枚举操作可能无法执行。 内部异常: InvalidOperationException:集合已修改;枚举操作可能无法执行。

这发生在b.Inlines.AddRange(span.Inlines) 行中。为什么这样?我不明白哪个集合发生了变化。

直接绑定到Text 不起作用。然后我只看到“System.Documents.Text.Span”,但看不到实际呈现的跨度。

【问题讨论】:

  • 两个音符。检查if (!(d is ExtendedTextBlock b)) 是多余的。不能在任何不是 ExtendedTextBlock 的 DependencyObject 上设置该属性。最好使用强制转换来获得InvalidCastException,以防代码以意想不到的方式使用。也使用else if 而不是if 语句链。
  • 感谢您的评论。嗯,我不确定。 if's 主要是因为我只是快速尝试了一下,通常只能同时发生其中一种情况,但您仍然是对的。改了。

标签: wpf


【解决方案1】:

不知道为什么会这样,但是将 Span.Inlines 复制到新集合可以解决问题:

using System.Linq;
...

b.Inlines.AddRange(span.Inlines.ToList());

【讨论】:

  • 它确实有效,但由于某种原因,文本显示没有任何效果(无下标)。我也尝试直接添加跨度,但后来我得到一个异常说Specified element is already the logical child of another element. Disconnect it first.。但是,如何保留下标?
  • 是的,我刚试过。它仅适用于数字,但不适用于字母。
  • 你需要一个支持它的字体。 MS Docs 示例使用FontFamily="Palatino Linotype"
  • 不,marked answer 中的一个 cmets 说存在一个已知错误(遗憾的是,指向 MS Connect 的链接不起作用,所以我不知道这是否与我们的错误相同'正在谈论)。尽管如此,它在设置 BaselineAlignment 属性而不是附加的 Typography.Variants 属性时仍然有效。
  • 嗯,对我来说它适用于FontFamily="Palatino Linotype"
猜你喜欢
  • 1970-01-01
  • 2011-07-30
  • 2011-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-02
  • 2010-12-20
相关资源
最近更新 更多