非固定格式文件概觀
非固定格式文件的設計是為最佳化檢視和可讀性。 非固定格式文件並不會設為某種預先定義的配置,而是會根據執行階段變數 (例如視窗大小、裝置解析度和選擇性的使用者喜好設定),動態調整及自動重排其內容。 此外,非固定格式文件提供進階文件功能,例如編頁和資料行。 本主題提供非固定格式文件和建立方式的概觀。
什麼是非固定格式文件
非固定格式文件的設計是會根據視窗大小、裝置解析度及其他環境變數來「自動重排內容」。 此外,非固定格式文件具備許多內建功能,包括搜尋、將可讀性最佳化的檢視模式,以及變更字型大小與外觀的能力。 當可讀性是使用文件的主要考量時,最好使用非固定格式文件。 相反地,固定格式文件的設計是靜態展示。 當來源內容的精確度很重要時,固定格式文件很有用。 如需不同文件類型的詳細資訊,請參閱 WPF 中的文件。
下圖顯示在數個不同大小的視窗中檢視非固定格式文件範例。 當顯示區域變更時,內容就會自動重排以充分利用可用的空間。
如上圖所示,非固定格式內容可以包含許多元件,包括段落、清單、映像等等。 這些元件會對應至程序性程式碼中標記和物件的項目。 稍後在本概觀的非固定格式相關的類別一節中,會詳述這些類別。 現在,先看看建立非固定格式文件的簡單程式碼範例,包含某些粗體文字的段落與清單。
<!-- This simple flow document includes a paragraph with some
bold text in it and a list. -->
<FlowDocumentReader xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<FlowDocument>
<Paragraph>
<Bold>Some bold text in the paragraph.</Bold>
Some text that is not bold.
</Paragraph>
<List>
<ListItem>
<Paragraph>ListItem 1</Paragraph>
</ListItem>
<ListItem>
<Paragraph>ListItem 2</Paragraph>
</ListItem>
<ListItem>
<Paragraph>ListItem 3</Paragraph>
</ListItem>
</List>
</FlowDocument>
</FlowDocumentReader>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace SDKSample
{
public partial class SimpleFlowExample : Page
{
public SimpleFlowExample()
{
Paragraph myParagraph = new Paragraph();
// Add some Bold text to the paragraph
myParagraph.Inlines.Add(new Bold(new Run("Some bold text in the paragraph.")));
// Add some plain text to the paragraph
myParagraph.Inlines.Add(new Run(" Some text that is not bold."));
// Create a List and populate with three list items.
List myList = new List();
// First create paragraphs to go into the list item.
Paragraph paragraphListItem1 = new Paragraph(new Run("ListItem 1"));
Paragraph paragraphListItem2 = new Paragraph(new Run("ListItem 2"));
Paragraph paragraphListItem3 = new Paragraph(new Run("ListItem 3"));
// Add ListItems with paragraphs in them.
myList.ListItems.Add(new ListItem(paragraphListItem1));
myList.ListItems.Add(new ListItem(paragraphListItem2));
myList.ListItems.Add(new ListItem(paragraphListItem3));
// Create a FlowDocument with the paragraph and list.
FlowDocument myFlowDocument = new FlowDocument();
myFlowDocument.Blocks.Add(myParagraph);
myFlowDocument.Blocks.Add(myList);
// Add the FlowDocument to a FlowDocumentReader Control
FlowDocumentReader myFlowDocumentReader = new FlowDocumentReader();
myFlowDocumentReader.Document = myFlowDocument;
this.Content = myFlowDocumentReader;
}
}
}
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Documents
Namespace SDKSample
Partial Public Class SimpleFlowExample
Inherits Page
Public Sub New()
Dim myParagraph As New Paragraph()
' Add some Bold text to the paragraph
myParagraph.Inlines.Add(New Bold(New Run("Some bold text in the paragraph.")))
' Add some plain text to the paragraph
myParagraph.Inlines.Add(New Run(" Some text that is not bold."))
' Create a List and populate with three list items.
Dim myList As New List()
' First create paragraphs to go into the list item.
Dim paragraphListItem1 As New Paragraph(New Run("ListItem 1"))
Dim paragraphListItem2 As New Paragraph(New Run("ListItem 2"))
Dim paragraphListItem3 As New Paragraph(New Run("ListItem 3"))
' Add ListItems with paragraphs in them.
myList.ListItems.Add(New ListItem(paragraphListItem1))
myList.ListItems.Add(New ListItem(paragraphListItem2))
myList.ListItems.Add(New ListItem(paragraphListItem3))
' Create a FlowDocument with the paragraph and list.
Dim myFlowDocument As New FlowDocument()
myFlowDocument.Blocks.Add(myParagraph)
myFlowDocument.Blocks.Add(myList)
' Add the FlowDocument to a FlowDocumentReader Control
Dim myFlowDocumentReader As New FlowDocumentReader()
myFlowDocumentReader.Document = myFlowDocument
Me.Content = myFlowDocumentReader
End Sub
End Class
End Namespace
下圖顯示此程式碼片段的外觀。
此範例使用 FlowDocumentReader 控制項來主控非固定格式內容。 如需非固定格式內容裝載控制項的詳細資訊,請參閱非固定格式文件類型。 Paragraph、List、ListItem 和 Bold 元素會以根據標記順序來控制內容格式。 例如,Bold 元素僅跨越段落中的部分文字,因此只有該部分文字是粗體。 如果您使用過 HTML,會覺得很熟悉。
如上圖中的反白顯示,非固定格式文件有數項內建功能︰
搜尋︰讓使用者對整份文件執行全文檢索搜尋。
檢視模式︰使用者可以選取偏好的檢視模式,包括單一頁面 (一次一頁) 檢視模式、一次兩頁 (書本閱讀格式) 檢視模式,以及以連續捲動 (無底邊) 檢視模式。 如需這些檢視模式的相關資訊,請參閱 FlowDocumentReaderViewingMode。
頁面導覽控制項︰如果文件的檢視模式使用頁面,則頁面導覽控制項會包括移至下一頁 (向下箭號) 或上一頁 (向上箭號) 的按鈕,以及目前頁碼和總頁數的指示器。 使用鍵盤方向鍵也可以翻頁。
縮放︰縮放控制項可讓使用者按下加號或減號按鈕,分別放大或縮小縮放層級。 縮放控制項也包括調整縮放層級的滑桿。 如需詳細資訊,請參閱Zoom。
您可以根據裝載非固定格式內容所用的控制項來修改這些功能。 下一節說明不同的控制項。
非固定格式文件類型
非固定格式文件內容的外觀和顯示方式,取決於裝載非固定格式內容的物件。 有四個控制項支援檢視非固定格式內容:FlowDocumentReader、FlowDocumentPageViewer、RichTextBox 和 FlowDocumentScrollViewer。 以下簡短說明這些控制項。
注意
需要 FlowDocument 方能直接主控非固定格式內容,因此所有這些檢視控制項都會取用 FlowDocument 來啟用非固定格式內容主控。
FlowDocumentReader
FlowDocumentReader 包含可讓使用者動態選擇各種檢視模式的功能,包括單頁 (一次顯示一頁) 檢視模式、一次顯示兩頁 (書本閱讀格式) 檢視模式,以及連續捲動 (無底邊) 檢視模式。 如需這些檢視模式的相關資訊,請參閱 FlowDocumentReaderViewingMode。 如果您不需要動態切換不同檢視模式的功能,FlowDocumentPageViewer 和 FlowDocumentScrollViewer 支援佔用較少資源的非固定格式內容檢視器,並可固定在特定檢視模式下執行。
FlowDocumentPageViewer 和 FlowDocumentScrollViewer
FlowDocumentPageViewer 會以單頁 (一次顯示一頁) 檢視模式顯示內容,FlowDocumentScrollViewer 會以連續捲動模式顯示內容。 FlowDocumentPageViewer 和 FlowDocumentScrollViewer 都可設定為固定的特定檢視模式。 FlowDocumentReader 可讓使用者動態選擇各種檢視模式 (如 FlowDocumentReaderViewingMode 所列舉之檢視模式),但其佔用的資源較 FlowDocumentPageViewer 或 FlowDocumentScrollViewer 多。
預設一定會顯示垂直捲軸,而水平捲動則會視需要顯示。 FlowDocumentScrollViewer 的預設 UI 不包含工具列,不過可套用 IsToolBarVisible 屬性來啟用內建工具列。
RichTextBox
如果您希望允許使用者編輯非固定格式內容,請選用 RichTextBox。 例如,如果您想建立一個編輯器,讓使用者可以管理資料表、斜體和粗體格式設定等,請選用 RichTextBox。 如需詳細資訊,請參閱 RichTextBox 概觀。
注意
RichTextBox 的非固定格式內容和其他控制項中的非固定格式內容運作方式並不完全相同。 例如,RichTextBox 中沒有欄標籤,因此無法自動調整大小。 此外,RichTextBox 不提供如搜尋、檢視模式、頁面導覽和縮放等非固定格式內容的一般內建功能。
建立非固定格式內容
非固定格式內容可以很複雜,其各種組成項目包括文字、圖片、資料表,甚至控制項等 UIElement 衍生類別。 若要了解如何建立複雜的非固定格式內容,下列幾點很重要︰
非固定格式相關的類別:非固定格式內中使用的每種類別都有特定用途。 此外,非固定格式類別之間的階層式關聯性可協助您了解如何使用它們。 例如,衍生自 Block 類的類別可包含其他物件,而衍生自 Inline 類的類別則可包含要顯示的物件。
內容結構描述︰非固定格式文件會需要大量的巢狀項目。 內容結構描述指定項目之間可能的父/子關聯性。
下列各節會一一詳細介紹這些區域。
非固定格式相關的類別
下圖顯示非固定格式內容中最常使用的物件︰
針對非固定格式內容的目的,有兩個重要分類︰
區塊衍生類別︰也稱為「區塊內容項目」或簡稱為「區塊項目」。 繼承自 Block 的元素可在相同的父元素下將元素分組,或將常見屬性套用至同一個群組。
內嵌衍生類別︰也稱為「內嵌內容項目」或簡稱為「內嵌項目」。 繼承自 Inline 的元素不是包含在區塊元素中,就是包含在另一個內嵌元素中。 內嵌項目通常用為轉譯到螢幕之內容的直接容器。 例如,Paragraph (區塊層級元素) 可包含 Run (內嵌元素),但實際上 Run 才包含要在螢幕上呈現的文字。
以下簡短描述這兩種分類中的每個類別。
區塊衍生類別
段落
Paragraph 通常用於將群組內容分成段落。 段落最簡單且最常見的用法是建立一段文字。
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Paragraph>
Some paragraph text.
</Paragraph>
</FlowDocument>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace SDKSample
{
public partial class ParagraphExample : Page
{
public ParagraphExample()
{
// Create paragraph with some text.
Paragraph myParagraph = new Paragraph();
myParagraph.Inlines.Add(new Run("Some paragraph text."));
// Create a FlowDocument and add the paragraph to it.
FlowDocument myFlowDocument = new FlowDocument();
myFlowDocument.Blocks.Add(myParagraph);
this.Content = myFlowDocument;
}
}
}
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Documents
Namespace SDKSample
Partial Public Class ParagraphExample
Inherits Page
Public Sub New()
' Create paragraph with some text.
Dim myParagraph As New Paragraph()
myParagraph.Inlines.Add(New Run("Some paragraph text."))
' Create a FlowDocument and add the paragraph to it.
Dim myFlowDocument As New FlowDocument()
myFlowDocument.Blocks.Add(myParagraph)
Me.Content = myFlowDocument
End Sub
End Class
End Namespace
不過,您也可以把其他內嵌衍生元素包含在其中,如下所示。
區段
Section 僅用於包含其他 Block 衍生元素。 它不會將任何預設的格式設定套用到其所包含的項目。 不過,Section 上設定的任何屬性值都會套用至其子元素。 區段也可讓您以程式設計的方式逐一查看其子集合。 Section 的用途與 HTML 中的 <DIV> 標籤相似。
以下範例中,三個段落定義在一個 Section 之下。 該區段的 Background 屬性值為 [紅色],因此段落的背景顏色亦為紅色。
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- By default, Section applies no formatting to elements contained
within it. However, in this example, the section has a Background
property value of "Red", therefore, the three paragraphs (the block)
inside the section also have a red background. -->
<Section Background="Red">
<Paragraph>
Paragraph 1
</Paragraph>
<Paragraph>
Paragraph 2
</Paragraph>
<Paragraph>
Paragraph 3
</Paragraph>
</Section>
</FlowDocument>
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Documents;
namespace SDKSample
{
public partial class SectionExample : Page
{
public SectionExample()
{
// Create three paragraphs
Paragraph myParagraph1 = new Paragraph(new Run("Paragraph 1"));
Paragraph myParagraph2 = new Paragraph(new Run("Paragraph 2"));
Paragraph myParagraph3 = new Paragraph(new Run("Paragraph 3"));
// Create a Section and add the three paragraphs to it.
Section mySection = new Section();
mySection.Background = Brushes.Red;
mySection.Blocks.Add(myParagraph1);
mySection.Blocks.Add(myParagraph2);
mySection.Blocks.Add(myParagraph3);
// Create a FlowDocument and add the section to it.
FlowDocument myFlowDocument = new FlowDocument();
myFlowDocument.Blocks.Add(mySection);
this.Content = myFlowDocument;
}
}
}
Imports System.Windows
Imports System.Windows.Media
Imports System.Windows.Controls
Imports System.Windows.Documents
Namespace SDKSample
Partial Public Class SectionExample
Inherits Page
Public Sub New()
' Create three paragraphs
Dim myParagraph1 As New Paragraph(New Run("Paragraph 1"))
Dim myParagraph2 As New Paragraph(New Run("Paragraph 2"))
Dim myParagraph3 As New Paragraph(New Run("Paragraph 3"))
' Create a Section and add the three paragraphs to it.
Dim mySection As New Section()
mySection.Background = Brushes.Red
mySection.Blocks.Add(myParagraph1)
mySection.Blocks.Add(myParagraph2)
mySection.Blocks.Add(myParagraph3)
' Create a FlowDocument and add the section to it.
Dim myFlowDocument As New FlowDocument()
myFlowDocument.Blocks.Add(mySection)
Me.Content = myFlowDocument
End Sub
End Class
End Namespace
BlockUIContainer
BlockUIContainer 可讓 UIElement 元素 (亦即 Button) 嵌入衍生自區塊的非固定格式內容。 InlineUIContainer (請參閱下方) 可在非固定格式內嵌衍生內容中嵌入 UIElement 元素。 BlockUIContainer 和 InlineUIContainer 很重要,因為除非 UIElement 包含在這兩個元素其中之一內,否則沒有其他辦法可在非固定格式內容中使用它。
以下範例說明如何使用 BlockUIContainer 元素在非固定格式內容中主控 UIElement 物件。
<FlowDocument ColumnWidth="400">
<Section Background="GhostWhite">
<Paragraph>
A UIElement element may be embedded directly in flow content
by enclosing it in a BlockUIContainer element.
</Paragraph>
<BlockUIContainer>
<Button>Click me!</Button>
</BlockUIContainer>
<Paragraph>
The BlockUIContainer element may host no more than one top-level
UIElement. However, other UIElements may be nested within the
UIElement contained by an BlockUIContainer element. For example,
a StackPanel can be used to host multiple UIElement elements within
a BlockUIContainer element.
</Paragraph>
<BlockUIContainer>
<StackPanel>
<Label Foreground="Blue">Choose a value:</Label>
<ComboBox>
<ComboBoxItem IsSelected="True">a</ComboBoxItem>
<ComboBoxItem>b</ComboBoxItem>
<ComboBoxItem>c</ComboBoxItem>
</ComboBox>
<Label Foreground ="Red">Choose a value:</Label>
<StackPanel>
<RadioButton>x</RadioButton>
<RadioButton>y</RadioButton>
<RadioButton>z</RadioButton>
</StackPanel>
<Label>Enter a value:</Label>
<TextBox>
A text editor embedded in flow content.
</TextBox>
</StackPanel>
</BlockUIContainer>
</Section>
</FlowDocument>
此範例的呈現方式請見下圖:
清單
List 的用途為建立分項或數值清單。 將 MarkerStyle 屬性設定為 TextMarkerStyle 列舉值,以決定清單樣式。 下例示範如何建立簡單的清單。
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<List>
<ListItem>
<Paragraph>
List Item 1
</Paragraph>
</ListItem>
<ListItem>
<Paragraph>
List Item 2
</Paragraph>
</ListItem>
<ListItem>
<Paragraph>
List Item 3
</Paragraph>
</ListItem>
</List>
</FlowDocument>
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Documents;
namespace SDKSample
{
public partial class ListExample : Page
{
public ListExample()
{
// Create three paragraphs
Paragraph myParagraph1 = new Paragraph(new Run("List Item 1"));
Paragraph myParagraph2 = new Paragraph(new Run("List Item 2"));
Paragraph myParagraph3 = new Paragraph(new Run("List Item 3"));
// Create the ListItem elements for the List and add the
// paragraphs to them.
ListItem myListItem1 = new ListItem();
myListItem1.Blocks.Add(myParagraph1);
ListItem myListItem2 = new ListItem();
myListItem2.Blocks.Add(myParagraph2);
ListItem myListItem3 = new ListItem();
myListItem3.Blocks.Add(myParagraph3);
// Create a List and add the three ListItems to it.
List myList = new List();
myList.ListItems.Add(myListItem1);
myList.ListItems.Add(myListItem2);
myList.ListItems.Add(myListItem3);
// Create a FlowDocument and add the section to it.
FlowDocument myFlowDocument = new FlowDocument();
myFlowDocument.Blocks.Add(myList);
this.Content = myFlowDocument;
}
}
}
Imports System.Windows
Imports System.Windows.Media
Imports System.Windows.Controls
Imports System.Windows.Documents
Namespace SDKSample
Partial Public Class ListExample
Inherits Page
Public Sub New()
' Create three paragraphs
Dim myParagraph1 As New Paragraph(New Run("List Item 1"))
Dim myParagraph2 As New Paragraph(New Run("List Item 2"))
Dim myParagraph3 As New Paragraph(New Run("List Item 3"))
' Create the ListItem elements for the List and add the
' paragraphs to them.
Dim myListItem1 As New ListItem()
myListItem1.Blocks.Add(myParagraph1)
Dim myListItem2 As New ListItem()
myListItem2.Blocks.Add(myParagraph2)
Dim myListItem3 As New ListItem()
myListItem3.Blocks.Add(myParagraph3)
' Create a List and add the three ListItems to it.
Dim myList As New List()
myList.ListItems.Add(myListItem1)
myList.ListItems.Add(myListItem2)
myList.ListItems.Add(myListItem3)
' Create a FlowDocument and add the section to it.
Dim myFlowDocument As New FlowDocument()
myFlowDocument.Blocks.Add(myList)
Me.Content = myFlowDocument
End Sub
End Class
End Namespace
注意
List 是唯一使用 ListItemCollection 來管理子元素的非固定格式元素。
Table
Table 的用途為建立資料表。 Table 與 Grid 元素相似,但具備更多功能,因此會佔用更多資源。 因為 Grid 是 UIElement,所以除非它包含在 BlockUIContainer 或 InlineUIContainer 中,否則無法在非固定格式內容中使用。 如需 Table 的詳細資訊,請參閱資料表概觀。
內嵌衍生類別
執行
Run 的用途為包含未格式化的文字。 您可能會希望 Run 物件大量用於非固定格式內容中。 不過標記中不需明確使用 Run 元素。 使用程式碼建立或管理非固定格式文件時,需要使用 Run。 例如,在以下標記中,第一個 Paragraph 明確指定了 Run 元素,但第二個卻沒有。 這兩個段落會產生相同的輸出。
<Paragraph>
<Run>Paragraph that explicitly uses the Run element.</Run>
</Paragraph>
<Paragraph>
This Paragraph omits the Run element in markup. It renders
the same as a Paragraph with Run used explicitly.
</Paragraph>
注意
從 .NET Framework 4 開始,Run 物件的 Text 屬性即為相依性屬性。 您可以將 Text 屬性繫結至 TextBlock 等資料來源。 Text 屬性完全支援單向繫結。 除了 RichTextBox 之外,Text 屬性也支援雙向繫結。 如需範例,請參閱 Run.Text。
Span
Span 可將其他內嵌內容元素群聚在一起。 Span 元素的內容不會沿用固有的呈現方式。 不過,繼承自 Span 的元素,包括 Hyperlink、Bold、Italic 和 Underline 都會將格式設定套用至文字。
以下為 Span 用於包含內嵌內容 (包括文字、Bold 元素和 Button) 的範例。
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Paragraph>
Text before the Span. <Span Background="Red">Text within the Span is
red and <Bold>this text is inside the Span-derived element Bold.</Bold>
A Span can contain more then text, it can contain any inline content. For
example, it can contain a
<InlineUIContainer>
<Button>Button</Button>
</InlineUIContainer>
or other UIElement, a Floater, a Figure, etc.</Span>
</Paragraph>
</FlowDocument>
以下的螢幕擷取畫面顯示此範例的轉譯方式。
InlineUIContainer
InlineUIContainer 可使 UIElement 元素 (亦即類似 Button 的控制項) 嵌入 Inline 內容元素中。 此內嵌元素相當於上文所述之 BlockUIContainer 內嵌元素。 以下為使用 InlineUIContainer 在 Paragraph 中插入 Button 內嵌元素的範例。
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Paragraph>
Text to precede the button...
<!-- Set the BaselineAlignment property to "Bottom"
so that the Button aligns properly with the text. -->
<InlineUIContainer BaselineAlignment="Bottom">
<Button>Button</Button>
</InlineUIContainer>
Text to follow the button...
</Paragraph>
</FlowDocument>
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Documents;
namespace SDKSample
{
public partial class InlineUIContainerExample : Page
{
public InlineUIContainerExample()
{
Run run1 = new Run(" Text to precede the button... ");
Run run2 = new Run(" Text to follow the button... ");
// Create a new button to be hosted in the paragraph.
Button myButton = new Button();
myButton.Content = "Click me!";
// Create a new InlineUIContainer to contain the Button.
InlineUIContainer myInlineUIContainer = new InlineUIContainer();
// Set the BaselineAlignment property to "Bottom" so that the
// Button aligns properly with the text.
myInlineUIContainer.BaselineAlignment = BaselineAlignment.Bottom;
// Asign the button as the UI container's child.
myInlineUIContainer.Child = myButton;
// Create the paragraph and add content to it.
Paragraph myParagraph = new Paragraph();
myParagraph.Inlines.Add(run1);
myParagraph.Inlines.Add(myInlineUIContainer);
myParagraph.Inlines.Add(run2);
// Create a FlowDocument and add the paragraph to it.
FlowDocument myFlowDocument = new FlowDocument();
myFlowDocument.Blocks.Add(myParagraph);
this.Content = myFlowDocument;
}
}
}
Imports System.Windows
Imports System.Windows.Media
Imports System.Windows.Controls
Imports System.Windows.Documents
Namespace SDKSample
Partial Public Class InlineUIContainerExample
Inherits Page
Public Sub New()
Dim run1 As New Run(" Text to precede the button... ")
Dim run2 As New Run(" Text to follow the button... ")
' Create a new button to be hosted in the paragraph.
Dim myButton As New Button()
myButton.Content = "Click me!"
' Create a new InlineUIContainer to contain the Button.
Dim myInlineUIContainer As New InlineUIContainer()
' Set the BaselineAlignment property to "Bottom" so that the
' Button aligns properly with the text.
myInlineUIContainer.BaselineAlignment = BaselineAlignment.Bottom
' Asign the button as the UI container's child.
myInlineUIContainer.Child = myButton
' Create the paragraph and add content to it.
Dim myParagraph As New Paragraph()
myParagraph.Inlines.Add(run1)
myParagraph.Inlines.Add(myInlineUIContainer)
myParagraph.Inlines.Add(run2)
' Create a FlowDocument and add the paragraph to it.
Dim myFlowDocument As New FlowDocument()
myFlowDocument.Blocks.Add(myParagraph)
Me.Content = myFlowDocument
End Sub
End Class
End Namespace
注意
標記中不需明確使用 InlineUIContainer 元素。 如果您省略上述步驟,編譯程式碼時,還是會建立 InlineUIContainer。
圖表和 Floater
Figure 和 Floater 的用途為在非固定格式文件中嵌入內容,其刊登位置屬性可自訂,不受主要非固定格式內容影響。 Figure 或 Floater 元素通常用於醒目提示或強調部分內容,在主要非固定格式內容中主控支援圖片或其他內容,或以有彈性的方式插入相關內容,例如廣告。
以下範例說明如何將 Figure 嵌入文字段落中。
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Paragraph>
<Figure
Width="300" Height="100"
Background="GhostWhite" HorizontalAnchor="PageLeft" >
<Paragraph FontStyle="Italic" Background="Beige" Foreground="DarkGreen" >
A Figure embeds content into flow content with placement properties
that can be customized independently from the primary content flow
</Paragraph>
</Figure>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy
nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi
enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis
nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure.
</Paragraph>
</FlowDocument>
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Documents;
namespace SDKSample
{
public partial class FigureExample : Page
{
public FigureExample()
{
// Create strings to use as content.
string strFigure = "A Figure embeds content into flow content with" +
" placement properties that can be customized" +
" independently from the primary content flow";
string strOther = "Lorem ipsum dolor sit amet, consectetuer adipiscing" +
" elit, sed diam nonummy nibh euismod tincidunt ut laoreet" +
" dolore magna aliquam erat volutpat. Ut wisi enim ad" +
" minim veniam, quis nostrud exerci tation ullamcorper" +
" suscipit lobortis nisl ut aliquip ex ea commodo consequat." +
" Duis autem vel eum iriure.";
// Create a Figure and assign content and layout properties to it.
Figure myFigure = new Figure();
myFigure.Width = new FigureLength(300);
myFigure.Height = new FigureLength(100);
myFigure.Background = Brushes.GhostWhite;
myFigure.HorizontalAnchor = FigureHorizontalAnchor.PageLeft;
Paragraph myFigureParagraph = new Paragraph(new Run(strFigure));
myFigureParagraph.FontStyle = FontStyles.Italic;
myFigureParagraph.Background = Brushes.Beige;
myFigureParagraph.Foreground = Brushes.DarkGreen;
myFigure.Blocks.Add(myFigureParagraph);
// Create the paragraph and add content to it.
Paragraph myParagraph = new Paragraph();
myParagraph.Inlines.Add(myFigure);
myParagraph.Inlines.Add(new Run(strOther));
// Create a FlowDocument and add the paragraph to it.
FlowDocument myFlowDocument = new FlowDocument();
myFlowDocument.Blocks.Add(myParagraph);
this.Content = myFlowDocument;
}
}
}
Imports System.Windows
Imports System.Windows.Media
Imports System.Windows.Controls
Imports System.Windows.Documents
Namespace SDKSample
Partial Public Class FigureExample
Inherits Page
Public Sub New()
' Create strings to use as content.
Dim strFigure As String = "A Figure embeds content into flow content with" & " placement properties that can be customized" & " independently from the primary content flow"
Dim strOther As String = "Lorem ipsum dolor sit amet, consectetuer adipiscing" & " elit, sed diam nonummy nibh euismod tincidunt ut laoreet" & " dolore magna aliquam erat volutpat. Ut wisi enim ad" & " minim veniam, quis nostrud exerci tation ullamcorper" & " suscipit lobortis nisl ut aliquip ex ea commodo consequat." & " Duis autem vel eum iriure."
' Create a Figure and assign content and layout properties to it.
Dim myFigure As New Figure()
myFigure.Width = New FigureLength(300)
myFigure.Height = New FigureLength(100)
myFigure.Background = Brushes.GhostWhite
myFigure.HorizontalAnchor = FigureHorizontalAnchor.PageLeft
Dim myFigureParagraph As New Paragraph(New Run(strFigure))
myFigureParagraph.FontStyle = FontStyles.Italic
myFigureParagraph.Background = Brushes.Beige
myFigureParagraph.Foreground = Brushes.DarkGreen
myFigure.Blocks.Add(myFigureParagraph)
' Create the paragraph and add content to it.
Dim myParagraph As New Paragraph()
myParagraph.Inlines.Add(myFigure)
myParagraph.Inlines.Add(New Run(strOther))
' Create a FlowDocument and add the paragraph to it.
Dim myFlowDocument As New FlowDocument()
myFlowDocument.Blocks.Add(myParagraph)
Me.Content = myFlowDocument
End Sub
End Class
End Namespace
下圖顯示此範例的轉譯方式。
Figure 和 Floater 有多處不同,用於不同的情況。
圖表:
可以定位︰可以設定其水平和垂直錨點,將它固定在頁面、內容、資料行或段落的相對位置。 您也可以使用它的 HorizontalOffset 和 VerticalOffset 屬性任意指定位移值。
可調整為超過一個資料行的大小︰您可將 Figure 的高度和寬度設為頁面、內容或資料行高度或寬度的倍數。 請注意,如果是頁面及內容,倍數不能大於 1。 例如,您可將 Figure 的寬度設為「0.5 頁」、「0.25 內容」或「2 資料行」。 您也可以將高度和寬度設為絕對像素值。
Floater:
無法定位,但會轉譯任何可用的空間。 您無法設定 Floater 的位移值或錨點。
無法調整為超過一個資料行的大小︰在預設情況下,Floater 的大小只有一個資料行。 它具備 Width 屬性,可設為絕對像素值,但若此值大於一個資料行的寬度,則會被忽略,floater 的大小仍為一個資料行。 您可以藉著設定正確的像素寬度,將其大小調整為小於一個資料行。但調整大小與資料行本身無關,所以「0.5 資料行」並非有效的 Floater 寬度表示法。 Floater 不具備高度屬性,亦無法設定高度,其高度取決於內容
Floater 分頁︰如果指定寬度的內容超過 1 個資料行的高度,floater 就會斷開並分頁至下一個資料行、下一頁等。
Figure 是放置獨立內容的好選擇,您可在此控制大小及置放位置,確保內容符合指定大小的最適大小。 Floater 是放置更多非固定格式內容的好選擇,這種非固定格式內容與主頁面內容相似,但會與主頁面內容分開。
LineBreak
LineBreak 可在非固定格式內容中放置分行符號。 下列範例示範 LineBreak 的用法。
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Paragraph>
Before the LineBreak in Paragraph.
<LineBreak />
After the LineBreak in Paragraph.
<LineBreak/><LineBreak/>
After two LineBreaks in Paragraph.
</Paragraph>
<Paragraph>
<LineBreak/>
</Paragraph>
<Paragraph>
After a Paragraph with only a LineBreak in it.
</Paragraph>
</FlowDocument>
以下的螢幕擷取畫面顯示此範例的轉譯方式。
流程集合項目
在上述許多範例中,BlockCollection 和 InlineCollection 的用途為以程式設計的方式建構非固定格式內容。 例如,若要在 Paragraph 中加入元素,您可以使用語法:
myParagraph.Inlines.Add(new Run("Some text"));
這會將 Run 新增至 Paragraph 的 InlineCollection。 這與找到標記中的 Paragraph 隱含的 Run 相同:
<Paragraph>
Some Text
</Paragraph>
以使用 BlockCollection 為例,以下範例會建立新的 Section,然後使用新增,在 Section 內容中新增 Paragraph。
Section secx = new Section();
secx.Blocks.Add(new Paragraph(new Run("A bit of text content...")));
Dim secx As New Section()
secx.Blocks.Add(New Paragraph(New Run("A bit of text content...")))
除了將項目新增至流程集合,您也可以移除項目。 以下範例為如何刪除 Span 中最近新增的 Inline 元素。
spanx.Inlines.Remove(spanx.Inlines.LastInline);
spanx.Inlines.Remove(spanx.Inlines.LastInline)
下列範例為如何清除 Span 的所有內容 (Inline 元素)。
spanx.Inlines.Clear();
spanx.Inlines.Clear()
以程式設計方式處理非固定格式內容時,您可能也會廣泛使用這些集合。
非固定格式元素採用 InlineCollection (內嵌) 或 BlockCollection (區塊) 方式來包含其子元素,會採用何種方式端視父元素可包含何種類型的子元素 (Block 或 Inline)。 下一節的<內容結構描述>會摘要說明非固定格式內容項目的內含項目規則。
注意
非固定格式內容還能選用第三種集合類型,ListItemCollection,但這種集合類型只能與 List 搭配使用。 此外,還有幾種集合類型可與 Table 搭配使用。 如需詳細資訊,請參閱資料表概觀。
內容結構描述
假設有多種不同的非固定格式內容項目,追蹤項目可以包含哪些子項目類型可能很累人。 下圖摘要說明流程項目的內含項目規則。 箭號代表可能的父/子關聯性。
上圖中可以看出,某個元素可允許哪些子元素的關鍵因素並非該元素是 Block 元素還是 Inline 元素。 例如,Span (Inline 元素) 只允許 Inline 子元素,而 Figure (亦為 Inline 元素) 只允許 Block 子元素。 因此,可以快速判斷哪些項目可以包含其他項目的圖表就很有用。 請看範例,了解在使用圖表的情形下如何建構 RichTextBox 的非固定格式內容。
1.RichTextBox 必須包含 FlowDocument,而 FlowDocument 又必須包含 Block 衍生物件。 以下是來自上圖的對應區段。
這是標記目前可能的樣子。
<RichTextBox>
<FlowDocument>
<!-- One or more Block-derived object… -->
</FlowDocument>
</RichTextBox>
2.根據圖表,有數個 Block 元素可供選擇,包括 Paragraph、Section、Table、List 和 BlockUIContainer (請參閱上述區塊衍生類別)。 假設我們想要 Table。 根據上圖,Table 包含 TableRowGroup,TableRowGroup 包含 TableRow,TableRow 包含 TableCell,TableCell 包含 Block 衍生物件。 以下為上圖中 Table 的對應區段。
以下是對應的標記。
<RichTextBox>
<FlowDocument>
<Table>
<TableRowGroup>
<TableRow>
<TableCell>
<!-- One or more Block-derived object… -->
</TableCell>
</TableRow>
</TableRowGroup>
</Table>
</FlowDocument>
</RichTextBox>
3.同樣地,TableCell 底下需要一或多個 Block 元素。 為求簡便,我們在儲存格中放入一些文字。 我們可以使用有 Run 元素的 Paragraph 來執行這項操作。 下圖為表中的對應區段,顯示 Paragraph 可採用 Inline 元素,但 Run (Inline 元素) 只能採用純文字。
以下是標記的完整範例。
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<RichTextBox>
<FlowDocument>
<!-- Normally a table would have multiple rows and multiple
cells but this code is for demonstration purposes.-->
<Table>
<TableRowGroup>
<TableRow>
<TableCell>
<Paragraph>
<!-- The schema does not actually require
explicit use of the Run tag in markup. It
is only included here for clarity. -->
<Run>Paragraph in a Table Cell.</Run>
</Paragraph>
</TableCell>
</TableRow>
</TableRowGroup>
</Table>
</FlowDocument>
</RichTextBox>
</Page>
自訂文字
文字通常是非固定格式文件中最普遍的內容類型。 雖然您可以使用前文介紹的物件控制大部分的文字轉譯方式,但有一些其他方法可處理本節討論的自訂文字。
文字裝飾
文字裝飾讓您對文字套用底線、頂線、基準線及刪除線效果 (請參閱下圖)。 這些裝飾皆使用 TextDecorations 屬性新增,包括 Inline、Paragraph、TextBlock 和 TextBox 等已公開的許多物件。
下列範例將示範如何設定 TextDecorations 的Paragraph 屬性。
<FlowDocument ColumnWidth="200">
<Paragraph TextDecorations="Strikethrough">
This text will render with the strikethrough effect.
</Paragraph>
</FlowDocument>
Paragraph parx = new Paragraph(new Run("This text will render with the strikethrough effect."));
parx.TextDecorations = TextDecorations.Strikethrough;
Dim parx As New Paragraph(New Run("This text will render with the strikethrough effect."))
parx.TextDecorations = TextDecorations.Strikethrough
下圖顯示此範例的轉譯方式。
下列圖片分別顯示轉譯的頂線、基準線和底線裝飾。
印刷樣式
大部分非固定格式相關內容都會公開 Typography 屬性,包括 TextElement、FlowDocument、TextBlock 和 TextBox。 這個屬性是用來控制文字的印刷特性/變化 (即小型或大型大寫字、上標和下標等等)。
下列示範以 Paragraph 做為範例元素,說明如何設定 Typography 屬性。
<Paragraph
TextAlignment="Left"
FontSize="18"
FontFamily="Palatino Linotype"
Typography.NumeralStyle="OldStyle"
Typography.Fraction="Stacked"
Typography.Variants="Inferior"
>
<Run>
This text has some altered typography characteristics. Note
that use of an open type font is necessary for most typographic
properties to be effective.
</Run>
<LineBreak/><LineBreak/>
<Run>
0123456789 10 11 12 13
</Run>
<LineBreak/><LineBreak/>
<Run>
1/2 2/3 3/4
</Run>
</Paragraph>
下圖顯示此範例的轉譯方式。
相反地,下圖顯示如何轉譯套用預設印刷樣式屬性的類似範例。
下列示範如何以程式設計的方式設定 Typography 屬性。
Paragraph par = new Paragraph();
Run runText = new Run(
"This text has some altered typography characteristics. Note" +
"that use of an open type font is necessary for most typographic" +
"properties to be effective.");
Run runNumerals = new Run("0123456789 10 11 12 13");
Run runFractions = new Run("1/2 2/3 3/4");
par.Inlines.Add(runText);
par.Inlines.Add(new LineBreak());
par.Inlines.Add(new LineBreak());
par.Inlines.Add(runNumerals);
par.Inlines.Add(new LineBreak());
par.Inlines.Add(new LineBreak());
par.Inlines.Add(runFractions);
par.TextAlignment = TextAlignment.Left;
par.FontSize = 18;
par.FontFamily = new FontFamily("Palatino Linotype");
par.Typography.NumeralStyle = FontNumeralStyle.OldStyle;
par.Typography.Fraction = FontFraction.Stacked;
par.Typography.Variants = FontVariants.Inferior;
Dim par As New Paragraph()
Dim runText As New Run("This text has some altered typography characteristics. Note" & "that use of an open type font is necessary for most typographic" & "properties to be effective.")
Dim runNumerals As New Run("0123456789 10 11 12 13")
Dim runFractions As New Run("1/2 2/3 3/4")
par.Inlines.Add(runText)
par.Inlines.Add(New LineBreak())
par.Inlines.Add(New LineBreak())
par.Inlines.Add(runNumerals)
par.Inlines.Add(New LineBreak())
par.Inlines.Add(New LineBreak())
par.Inlines.Add(runFractions)
par.TextAlignment = TextAlignment.Left
par.FontSize = 18
par.FontFamily = New FontFamily("Palatino Linotype")
par.Typography.NumeralStyle = FontNumeralStyle.OldStyle
par.Typography.Fraction = FontFraction.Stacked
par.Typography.Variants = FontVariants.Inferior
如需印刷樣式的詳細資訊,請參閱 WPF 中的印刷樣式。