2009-04-08 28 views
2

一個WPF FlowDocument只能屬於一個RichTextBox。但是,我們希望使用單個文檔,可以在UI中的不同時間點(空間和時間)進行操作。它永遠不會發生有兩個RichTextBoxes同時顯示單個文檔(不能,因爲WPF會抱怨)。共享FlowDocuments

使用MemoryStreamXamlReader/Writer不會在這裏工作,因爲我們想保留一個單一的文件,無論它是用來反映變化,所以複製它每次都是出來。

有沒有其他可行的方法來實現這一目標?你可以使用什麼作爲潛在模型來創建FlowDocument左右?

澄清:使用該文檔的RichTextBoxes不再可見或邏輯/視頻樹的任何地方,當一個又一個將被實例化。雖然我可能無法強制他們已經被GC吃掉了。看起來這會在從窗口中刪除RichTextBox之後立即重新使用文檔時導致問題;仍然會拋出異常,該文檔已被其他控件使用。

基本上是有一組接連顯示一個「嚮導頁」,它可能發生,我們再利用兩個連續的「頁面」文檔,但每次都實例化一個新RTBox。也許有問題或更好的方法?

回答

0

根據你的嚮導是如何構建的,我實際上推薦你簡單地將頁面移動RichTextBox。 WPF控件可以根據需要'unparented'和'reparented',所以只需在整個嚮導中共享的上下文中使RichTextBox實例可用,並確保您在頁面之間移動時保持不變/重新加載。這也有利於在嚮導的頁面中保存任何樣式或對編輯器狀態的更改(這可能是可取的)。

如果不能共享跨頁RichTextBox的情況下,我覺得有一種方法來撇清從原來的RichTextBox的文檔。看來,爲了從RichTextBox1中取消關聯文檔,您必須爲RichTextBox1提供一個新文檔。您不能將RichTextBox1.Document設置爲null,但您可以將RichTextBox1.Document設置爲新的FlowDocument(),我相信這會起作用。我無法現在來測試這個權利,但我看到它在這個MSDN論壇主題的帖子的最後建議:

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/797bfc96-cf24-4071-bff8-ce8c4a7b897b

0

如果只有一個編輯器是在任何給定時間界面上顯示,我想這將有可能在活動編輯器的LostFocus事件的所有編輯器中的內容同步。

如果需要在應用程序的另一個當前可見部分中立即反映一個編輯器中的更改,則可以使用Rectangle來僞造它,例如填充是指引活動編輯器的VisualBrush以及Rectangle的寬度和高度被綁定到編輯器的實際寬度和高度。棘手的部分是以相對無縫的方式處理活動編輯器切換。

編輯:我想我不明白你爲什麼不能做嚮導頁面之間移動時XamlWriter.Save/XamlReader.Parse序列,但是......怎麼樣使用相同的RichTextBox的實例中的所有時間並在該頁面變爲可見/活動時將它重新保存到每個頁面中的容器?

+0

我在這個問題上詳細闡述了一下。我們無限期地不需要立即在用戶界面的其他地方反映這些變化。但一個文件拒絕被多次使用,看起來,這可以通過XamlWriter/Reader爲靜態內容繞過,但不適用於動態的東西:( – Joey 2009-04-08 14:52:55

4

的FlowDocument的不能直接一些的RichTextBox控制共享..

所以,你需要 '分離' 該文件第一...

所以

RTB2.Document = RTB1.Document; 

不會工作,並會導致您的異常..

FlowDocument doc = RTB1.Document; 
RTB1.Document = new FlowDocument(); //Document cannot be null, so therefor the new FlowDocument instance 
RTB2.Document = doc; 

會像一個魅力...

我的代碼示例:

的XAML:

<Window x:Class="WpfApplication2.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"> 

    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition /> 
      <ColumnDefinition /> 
     </Grid.ColumnDefinitions> 

     <Grid.RowDefinitions> 
      <RowDefinition /> 
      <RowDefinition Height="Auto" /> 
     </Grid.RowDefinitions> 


     <RichTextBox x:Name="RTB1" /> 

     <RichTextBox x:Name="RTB2" Grid.Column="1" /> 

     <Button x:Name="button" Grid.Row="1" Grid.ColumnSpan="2" Content="click" Click="button_Click" /> 

    </Grid> 

</Window> 

後面的代碼..

public partial class Window1 : Window 
{ 
    public Window1() 
    { 
     InitializeComponent(); 
    } 

    private void button_Click(object sender, RoutedEventArgs e) 
    { 
     FlowDocument doc = RTB1.Document; 
     RTB1.Document = new FlowDocument(); 
     RTB2.Document = doc; 
    } 
} 

它不是在書裏最漂亮的,但它的作品...

希望這有助於..

+1

我剛剛使用了這段代碼,它真是太神奇了 'Private Sub TradeTextBoxDocument(ByRef源作爲RichTextBox中,爲ByRef目的地的RichTextBox) 昏暗的流量作爲FlowDocument的= source.Document source.Document =新的FlowDocument destination.Document =流量 結束子」 – DoomVroom 2015-06-24 16:30:35

0

流文件不能共享,所以你必須分離。

string flowDocument = XamlWriter.Save(RTF1.Document); 
RichTextBox RTF2= new RichTextBox(); 
RTF2.Document = XamlReader.Load(new MemoryStream(Encoding.Default.GetBytes(flowDocument))) as FlowDocument; 
+0

那不是分離,這是序列化和反序列化。請注意,我主宰在這個問題中解決這個問題(大約六年前)。 – Joey 2015-05-13 06:19:29