在WPF中的TextBlock中显示图片

15

我正在开发一个简单的聊天应用程序。目前,消息绑定到一个自定义样式的列表框,就像这样(简化的 XAML 代码):

<ListBox ItemsSource="{Binding MessageCollection}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Text}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

现在我想能够将图像(如表情符号)放入显示的消息文本中。是否有任何方法可以使用TextBlock(或任何其他标准组件)实现此目的,还是需要使用某些特殊控件?

谢谢提前

6个回答

57

只需使用InlineUIContainer。

<TextBlock TextWrapping="Wrap">
    <Run>Some text.</Run>
    <InlineUIContainer>
        <Image Source="http://sstatic.net/stackoverflow/img/apple-touch-icon.png" Height="20"></Image>
    </InlineUIContainer>
    <Run>Some more text.</Run>
</TextBlock>

如何使 InlineUIContainer 垂直居中对齐? - huang
@JoeHuang BaselineAlignment = "中心对齐"? - jnm2

4

文本块的内容始终只是一系列内联元素,因此您应该使用InlineUIContainer。您可以将此容器作为TextBlock中的Inlines之一插入到任何需要显示图像的位置,与文本Runs交替出现。您可以解析消息并同时将找到的标记(文本或图像)添加到TextBlock的Inlines集合中。


1

您可以使用值转换器将文本转换为另一种类型,该类型具有由文本或笑脸组成的段落列表(按它们出现的顺序)。

然后,您可以使用数据模板绑定到该新类型,并适当地显示文本和笑脸。


请问您能否详细解释第二部分(或者给我提供文档/示例链接)?我理解第一部分,但不知道如何将两种不同的数据类型映射到不同的元素。 - lacop

1

如果你想要图片实际上在文本中(就像表情符号一样),那么你需要做一些工作。这听起来像是我真正想要一个用户控件的少数几次之一,其目的是扫描文本寻找表情符号值并动态构建数据模板。

记住,在XAML中你能做的任何事情都可以在代码中完成,所以我想到的代码会遵循这个一般思路:

  1. 扫描文本以查找表情符号值并创建数据元素值列表。
  2. 创建DockPanel。
  3. 对于列表中的每个元素,添加TextBlock或Image(基于值)。
  4. 将此.Content设置为DockPanel。

我认为像这样的东西实际上是你正在寻找的,但如果你只想要一个图像,那么ValueConverter建议会起作用。


我喜欢这个,听起来相当简单。但是我担心文本换行...我会尝试实现它并看看它的工作原理。谢谢。 - lacop
这是一个很好的观点。您可能需要进行一些测量并根据需要分割文本以获得正确的换行效果。只有在表情符号存在时才会出现问题。 - Joel Cochran
无论如何,我似乎找不到方法来做到这一点。我已经创建了自定义用户控件,但我不知道如何覆盖呈现机制并用所需的代码发出TextBox/Image元素。你能给我一个提示吗? - lacop
既然我需要进行测量,那么自己渲染文本和图像不是更容易吗?(通过覆盖渲染方法并使用绘图工具) - lacop
不要把它看作是覆盖渲染机制:这是我们在WinForms中做的事情。在这里,您只需将元素添加到DockPanel中:DockPanel panel = new DockPanel(); panel.Add(new TextBlock("value")); panel.Add(new Image("source"));等等。 - Joel Cochran
我没有手写过任何WPF,所以上面的是伪代码 - 你需要找到正确的属性等。而且所有这些可能都在DataTemplate中。 - Joel Cochran

1

我最近也遇到了这个问题,我通过以下方式解决:

创建一个ListBox ItemTemplate,其中包含一个ItemsControl,该ItemsControl具有ItemsPanelTemplate中的WrapPanel,然后使用IValueConverter将我的字符串绑定到ItemsControl的ItemsSource,并在其中包含所有逻辑。

拆分单词并查询/搜索表情符号字符串、超链接等,创建TextBlock、Image、Hyperlink、Button元素并设置值和事件处理程序。

在函数中创建一个List<UIElement>,并使用您生成的控件填充列表,将列表作为IValueConverter的Convert函数中的对象返回。

因为您在其中使用了WrapPanel,所以可以实现自动换行。


-1
使用Image元素代替TextBlock,并使用转换器将文本值映射到笑脸图像。
<ListBox ItemsSource="{Binding MessageCollection}">
<ListBox.ItemTemplate>
    <DataTemplate>
        <Image Source="{Binding Text, Converter={StaticResource MyImageConverter}}"/>
    </DataTemplate>
</ListBox.ItemTemplate>


但这只允许在消息中添加图像,对吧?我想要的是将文本和图像组合在一条消息中。 - lacop
数据模板可以是你想要的任何形式。例如: <DataTemplate> <Grid> <TexBlock .../> <Image .../>
<...其他控件...> </Grid> </DataTemplate>
- ema

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接