数据绑定TextBlock.Inlines [英] Data binding the TextBlock.Inlines

查看:677
本文介绍了数据绑定TextBlock.Inlines的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的WPF应用程序从后端服务中收到需要在UI中显示的消息流。这些消息差异很大,我想为每条消息提供不同的视觉布局(字符串格式,颜色,字体,图标等)。



我希望能够为每个消息创建一个内联(Run,TextBlock,Italic等),然后以某种方式将它们全部放在一个 ObservableCollection<> 并使用他的魔术WPF数据绑定在我的TextBlock.Inlines在UI中。我找不到如何做到这一点,这是可能的吗?

解决方案

这是不可能的,因为 TextBlock.Inlines 属性不是依赖属性。只有依赖属性可以成为数据绑定的目标。



根据您的确切布局要求,您可以使用 ItemsControl ,其 ItemsPanel 设置为 WrapPanel 及其 ItemsSource 设置为您的收藏。 (这里可能需要一些实验,因为 Inline 不是一个 UIElement ,所以它的默认渲染可能会使用 ToString()而不是显示。)



或者,您可能需要构建一个新的控件,例如 MultipartTextBlock ,可绑定 PartsSource 属性和 TextBlock as其默认模板。当您设置 PartsSource 时,您的控件将附加一个 CollectionChanged 事件处理程序(直接或通过CollectionChangedEventManager),并更新 TextBlock.Inlines 从代码中收集,因为 PartsSource 集合已更改。



<在任一情况下,如果您的代码直接生成 Inline 元素(因为 Inline 可以'同时在两个地方使用)。您也可以考虑公开文本,字体等的抽象模型(即视图模型),并通过创建实际的 Inline DataTemplate 。这也可能提高可测试性,但显然增加了复杂性和努力。


My WPF App receives a stream of messages from a backend service that I need to display in the UI. These messages vary widely and I want to have different visual layout (string formats, colors, Fonts, icons, whatever etc.) for each message.

I was hoping to just be able to create an inline (Run, TextBlock, Italic etc) for each message then somehow put them all in a ObservableCollection<> and using he magic of WPF Data Binding on my TextBlock.Inlines in the UI. I couldn't find how to do this, is this possible?

解决方案

This is not possible because the TextBlock.Inlines property is not a dependency property. Only dependency properties can be the target of a data binding.

Depending on your exact layout requirements you may be able to do this using an ItemsControl, with its ItemsPanel set to a WrapPanel and its ItemsSource set to your collection. (Some experimentation may be required here because an Inline is not a UIElement, so its default rendering will probably be done using ToString() rather than being displayed.)

Alternatively, you may need to build a new control, e.g. MultipartTextBlock, with a bindable PartsSource property and a TextBlock as its default template. When the PartsSource was set your control would attach a CollectionChanged event handler (directly or via CollectionChangedEventManager), and update the TextBlock.Inlines collection from code as the PartsSource collection changed.

In either case, caution may be required if your code is generating Inline elements directly (because an Inline can't be used in two places at the same time). You may alternatively want to consider exposing an abstract model of text, font, etc. (i.e. a view model) and creating the actual Inline objects via a DataTemplate. This may also improve testability, but obviously adds complexity and effort.

这篇关于数据绑定TextBlock.Inlines的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆