2009-04-08 3 views
2

A WPF FlowDocument может принадлежать только одному RichTextBox. Однако мы хотели бы использовать один документ, который можно манипулировать в разных точках (в пространстве и времени) в пользовательском интерфейсе. Никогда не будет, что есть два RichTextBoxes, одновременно отображающий один документ (и не может, потому что WPF будет жаловаться).Совместное использование FlowDocuments между несколькими RichTextBoxes

Использование MemoryStream и XamlReader/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 активного редактора.

Если изменения в одном редакторе должны быть немедленно отображены в другой видимой в настоящее время части приложения, вы можете подделать его с помощью прямоугольника, скажем, где Fill был VisualBrush, ссылаясь на активный редактор, а также на ширину и высоту Rectangle были связаны с фактической шириной и высотой редактора. Трудная часть будет относиться к активному редактору редактора относительно плавным образом.

EDIT: Я предполагаю, что я не понимаю, почему вы не можете сделать последовательность XamlWriter.Save/XamlReader.Parse при перемещении между страницами мастера, но ... что об использовании того же экземпляра RichTextBox все время и переустанавливать его в контейнер на каждой странице, когда эта страница становится видимой/активной?

+0

Я разработал немного больше в вопросе. Нам совершенно не нужно отражать эти изменения сразу в другом месте пользовательского интерфейса. Но Документ не используется более одного раза, по-видимому, который можно обойти с помощью XamlWriter/Reader для статического контента, но не для динамических материалов :( – Joey

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) Dim потока As FlowDocument = source.Document source.Document = Новый FlowDocument destination.Document = поток End Sub» – DoomVroom

0

Flow документ не может делиться, поэтому вам нужно отсоединиться.

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

Это не отсоединение, что это сериализации и десериализации. Обратите внимание, что я вынес решение из этого подхода в вопросе (около шести лет назад). – Joey

Смежные вопросы