【问题标题】:Run vs. Content vs. Text in WPFWPF 中的运行与内容与文本
【发布时间】:2015-03-28 12:02:53
【问题描述】:

在 WPF(甚至是 Windows 8 或 8.1 应用程序)中,您可以通过三种可能的方式在控件中添加文本。

  1. Run 元素内的TextBlock 元素

    <TextBlock>
        <Run>My text</Run>
    </TextBlock>
    
  2. Text 属性作为TextBlock 元素的属性

    <TextBlock Text="My text" />
    
  3. Text 属性作为 TextBlock 元素内的元素

    <TextBlock>
        <TextBlock.Text>my text</TextBlock.Text>
    </TextBlock>`
    

这三种方法有什么区别?为什么你必须使用Text 来代替TextBlockContent 来代替ComboboxItem

【问题讨论】:

  • 有在线文档和几本关于 WPF 的好书,其中详细解释了这些控件及其差异。
  • @Hein 你是如何编译 3. 和 4. 的?你能添加更多代码吗?在我的示例应用程序中,它不会编译

标签: c# wpf xaml wpf-controls


【解决方案1】:

具有Text 属性的控件只能接受字符串,并以该控件处理的特定方式呈现。此类控件的示例是 TextBlockTextBox

具有Content 属性的控件实际上可以将任何object 设置为该属性。这些控件通常将值转发到ContentPresenter 上的Content 属性。 ContentPresenter Class 文档有这个相关的块:

ContentPresenter 使用以下逻辑来显示内容:

  • 如果 ContentPresenter 上的 ContentTemplate 属性已设置,ContentPresenter 会将该 DataTemplate 应用于 Content 属性,并显示生成的 UIElement 及其子元素(如果有)。有关 DataTemplate 对象的更多信息,请参阅数据模板概述。
  • 如果 ContentPresenter 上的 ContentTemplateSelector 属性已设置,ContentPresenter 会将适当的 DataTemplate 应用于 Content 属性,并显示生成的 UIElement 及其子元素(如果有)。
  • 如果存在与 Content 类型关联的 DataTemplate,ContentPresenter 会将该 DataTemplate 应用于 Content 属性,并显示生成的 UIElement 及其子元素(如果有)。
  • 如果 Content 是 UIElement 对象,则显示 UIElement。如果 UIElement 已有父元素,则会发生异常。
  • 如果存在将 Content 类型转换为 UIElement 的 TypeConverter,则 ContentPresenter 使用该 TypeConverter 并显示生成的 UIElement。
  • 如果存在将 Content 类型转换为字符串的 TypeConverter,ContentPresenter 将使用该 TypeConverter 并创建一个 TextBlock 来包含该字符串。显示文本块。
  • 如果内容是 XmlElement,则 InnerText 属性的值显示在 TextBlock 中。
  • ContentPresenter 调用 Content 的 ToString 方法并创建一个 TextBlock 以包含 ToString 返回的字符串。显示文本块。

对于TextBlock 类,您可以选择设置Text 属性或设置Inlines 属性。设置Text 只会渲染文本。设置 Inlines(如果您将内容放在 xaml 标记的正文中,这是默认设置)允许您格式化文本。例如,您可以使用 Run 并将其 FontWeight 设置为 Bold 以使句子中的某个单词或短语变为粗体。您可以使用LineBreak 插入新行。您甚至可以使用 InlineUIContainer 在文本中插入自定义 UI 元素。任何派生自 Inline 类的东西都可以放在这个集合中。

TextBlock 适用于简单的格式化文本。如果您想要更强大的文档样式功能,可以查看FlowDocument,它被RichTextBoxFlowDocumentScrollViewerFlowDocumentReader 等控件使用。

&lt;TextBlock Text="something" /&gt;&lt;TextBlock&gt;&lt;TextBlock.Text&gt;something&lt;/TextBlock.Text&gt;&lt;/TextBlock&gt; 之间的区别而言,实际上没有区别。这些只是您可以在 xaml 文件中设置属性的两种不同方式。第二个版本通常仅在您需要在 setter 中定义其他元素时使用。

【讨论】:

    【解决方案2】:

    关于“属性元素”的简短介绍

    这只是对 Xaviers 出色答案的补充说明。

    其实两者并没有太大区别:

    <TextBlock Text="something" />
    

    <TextBlock><TextBlock.Text>something</TextBlock.Text></TextBlock>
    

    那是因为Text 属性是String 类型,这是一个简单的类型,可以像Text="something" 一样直接设置。

    上面示例中的后一种语法称为“属性元素”。 通常用于将元素的属性设置为复杂类型时使用。

    例子:

    <Button>
      <Button.Content>
         <Rectangle Height="20", Width="20", Fill="Black"/>
      </Button.Content>
    </Button>
    

    在此示例中,您可以直接设置“矩形”而不使用Button.Content,但对于其他示例,该语法可用于设置复杂类型的属性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多