【发布时间】: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