[WPF] 初探 FlowDocument 文件(1)

究竟為什麼要有 FlowDocument 呢?不是已經有 XPS 文件檔了?其實 FlowDocument 與 XPS 的最大差別在於 XPS是編譯過的文件檔,一旦產生出來後就不可以再修改了。而 FlowDocument 是一個XAML檔,不需要編譯,就可以在 WPF 畫面中透過 FlowDocumentReader 等控制項呈現其內容

緣起:

為什麼寫這篇文章呢?約 2009 年的時候,筆者有寫過一篇如何透過可程式化的方式產生 XPS 文件如何手動或程式化產生XPS文件,之中也說明了 XPS 的呈現方式其實也是使用 WPF 中的一部份的子功能,那什麼是 FlowDocument 呢?那又為什麼需要 FlowDocument 呢?而另外又有 XPS 文件,初接觸 WFP 的開發人員總是會霧沙沙的問這個問題。我們往下看見分曉!

FlowDocument 與 XPS 文件的差異:

究竟為什麼要有 FlowDocument 呢?不是已經有 XPS 文件檔了?其實 FlowDocument 與 XPS 的最大差別在於 XPS是編譯過的文件檔,一旦產生出來後就不可以再修改了。而 FlowDocument 是一個XAML檔,不需要編譯,就可以在 WPF 畫面中透過 FlowDocumentReader 等控制項呈現其內容,且編輯方式如同編輯一般 XAML 檔沒什麼不同。其中,且定義了 Table、List、Secion、Paragraph、BlockUIContainer 等區段用以顯示、編排其內容。而什麼時候會用到 FlowDocument 呢?一般來說應用程式中的 About 等相關內容,以前 Windows Form 程式可能就直接在 UI 上,用著沒什麼編排功能的 Label、PictureBox 拼拼湊湊,像個樣子就好。不過現在有 FlowDocument 後,事情就變得容易多了,因為 Document 的內容也變成是可維護的,也不需要重新編譯程式。而當然,編輯 XAML 就像編輯 HTML 一樣,非常的容易。

FlowDocument 的組成:

前面提到過,一個 FlowDocument 中包含 5 種區塊方式可供編排其內容,相關說明如下:

  • Table:表格,如同 HTML 的表格一般。
  • List:在畫面上顯示清單的結構,內部其實也是透過 ListItems 物件來達成。
  • Section:有點像群組方式,顯示多個區塊內容。
  • Paragraph:主要用來顯示文字內容,通常是一個 InLine 的集合物件。
  • BlockUIContainer:可以容納一個 UIElement 物件。

建立一個 FlowDocument 檔案:

一般建立一個 FlowDocument 的檔案透過VS2010加入 (中文翻作非固定格式文件),或手動建立都可以。如下畫面:

image

它的結構如下,一個以 FlowDocument 標籤包起來的內容 :

   1:  <FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   2:                ColumnWidth="400" FontSize="14" FontFamily="Georgia">
   3:  
   4:  </FlowDocument>

 

 

首先,我們就測試的加入一些內容如下:

   1:  <FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   2:                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   3:                ColumnWidth="400" FontSize="14" FontFamily="Georgia">
   4:  
   5:      <Paragraph FontSize="18" Background="Red">FlowDocument 測試</Paragraph>
   6:      <Paragraph>不需要編譯,就可以在 WPF 畫面中透過 FlowDocumentReader 等控制項呈現其。這是一個 FlowDocument 測試內容,,且編輯方式如同編輯一般 XAML 檔沒什麼不同。其中,且定義了 Table、List、Secion、Paragraph、BlockUIContainer 等區段用以顯示、編排其內容。而什麼時候會用到 FlowDocument 呢?一般來說應用程式中的 About 等相關內容</Paragraph>
   7:          <List>
   8:              <ListItem>
   9:                  <Paragraph>項目 1</Paragraph>
  10:              </ListItem>
  11:              <ListItem>
  12:                  <Paragraph>項目 2</Paragraph>
  13:              </ListItem>
  14:              <ListItem>
  15:                  <Paragraph>項目 3</Paragraph>
  16:              </ListItem>
  17:              <ListItem>
  18:                  <Paragraph>項目 4</Paragraph>
  19:              </ListItem>
  20:              <ListItem>
  21:                  <Paragraph>項目 5</Paragraph>
  22:              </ListItem>
  23:          </List>
  24:  </FlowDocument>

 

 

一個 FlowDocument 的 XAML 文件可以直接在 IE 下預覽內容

image

因為IE 即是預設的預覽器。您也可以直接寫死在 WPF 的 Window 中,如下圖:

image

 

它可直接顯示於 WPF 的 Window 中,在 WPF 提供了三種容器元件的呈現方式:

  • FlowDocumentPageViewer:以分頁模式來檢視文件內容。

image

  • FlowDocumentScrollViewer:檢視時不對文件進行分頁,只以 ScrollBar 捲動的方式來捲動內容。

image

  • FlowDocumentReader:是最完整的讀取器,它結合了上面兩種所有的功能,並又增加了搜尋的功能,這也是最常被使用的。

 

到這裡各位應該也有發現,其實WPF 的子系統預設就是用 FlowDocumentReader 來顯示文件。如果您將 FlowDocumentScrollViewer 的標籤拿掉,只保留 FlowDocument ,這實呈現的方式也是 FlowDocumentReader

image

而當然,上面都不是最好的方式,通常會撰寫一些程式碼,將 XAML 的 FlowDocument 作程外部檔案,需要時才將它讀去至畫面中。這麼一來我們只需要維護 FlowDocument 的 XAML 檔案即可,不需要重新編譯 WPF 應用程式。筆者在這邊新增一個 WPF Window ,並在 Window_Loaded 的事件中撰寫如下程式:

   1:              string content = File.ReadAllText(@"..\..\FlowDocument1.xaml");
   2:              StringReader sr = new StringReader(content);
   3:              XmlReader xr = XmlReader.Create(sr);
   4:              try
   5:              {
   6:                  FlowDocument doc = (FlowDocument)XamlReader.Load(xr);
   7:                  fdr1.Document = doc;
   8:              }
   9:              finally
  10:              {
  11:                  xr.Close();
  12:                  sr.Close();
  13:              }

 

 

執行後便可動態的讀入 FlowDocuemnt 的內容,如下執行結果:

image

結語:

基本上的運用大致上如此,有機會筆者再介紹其他的應用方式。在撰寫這篇文章時也發現了蹂躪大在2009 年也有寫過 [WPF]FlowDocument 的內容 ^_^。


 

簽名:

學習是一趟奇妙的旅程

這當中,有辛苦、有心酸、也有成果。有時也會有瓶頸。要能夠繼續勇往直前就必須保有一顆最熱誠的心。

軟體開發之路(FB 社團)https://www.facebook.com/groups/361804473860062/

Gelis 程式設計訓練營(粉絲團)https://www.facebook.com/gelis.dev.learning/


 

如果文章對您有用,幫我點一下讚,或是點一下『我要推薦,這會讓我更有動力的為各位讀者撰寫下一篇文章。

非常謝謝各位的支持與愛護,小弟在此位各位說聲謝謝!!! ^_^