Совместное использование FlowDocuments между несколькими RichTextBoxes - PullRequest
2 голосов
/ 08 апреля 2009

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

Использование MemoryStream и XamlReader / Writer не сработает, так как мы хотели бы сохранить один документ и отражать изменения, где бы он ни использовался, поэтому копируйте его каждый раз.

Есть ли другой жизнеспособный способ добиться этого? Что-то, что вы могли бы использовать в качестве базовой модели для создания FlowDocument или около того?

Пояснение: RichTextBox, которые используют Документ, больше не видны или находятся где-либо в логическом / визуальном дереве, когда будет создан другой экземпляр. Хотя я, вероятно, не могу обеспечить, чтобы они уже были съедены GC. По-видимому, это вызывает проблему при повторном использовании документа сразу после удаления RichTextBox из окна; это все еще вызывает исключение, что Документ уже используется в другом элементе управления.

По сути, у вас есть набор "страниц мастера", которые отображаются одна за другой, и может случиться, что мы повторно используем Документ на двух последовательных "страницах", но каждый раз создаем новый RTBox. Может быть, есть проблема или лучше?

Ответы [ 4 ]

4 голосов
/ 16 апреля 2009

FlowDocument не может совместно использоваться несколькими элементами управления RichTextBox напрямую.

Так что вам нужно сначала отсоединить этот документ ...

So

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;
    }
}

Это не самая красивая книга, но она работает ...

Надеюсь, это поможет ..

0 голосов
/ 13 мая 2015

Потоковым документом нельзя поделиться, поэтому необходимо отсоединить.

string flowDocument = XamlWriter.Save(RTF1.Document);
RichTextBox RTF2= new RichTextBox();
RTF2.Document = XamlReader.Load(new MemoryStream(Encoding.Default.GetBytes(flowDocument))) as FlowDocument; 
0 голосов
/ 15 апреля 2009

В зависимости от того, как устроен ваш мастер, я рекомендую вам просто переместить RichTextBox со страницы на страницу. Элементы управления WPF могут быть «незапятнаны» и «перекомпонованы» по желанию, поэтому просто сделайте экземпляр RichTextBox доступным в контексте, доступном всему мастеру, и убедитесь, что вы не родительский / родительский, когда переходите со страницы на страницу. Это также дает преимущество сохранения любых стилей или изменений в состоянии редакторов на страницах мастера (что, вероятно, желательно).

Если невозможно разделить экземпляр RichTextBox по страницам, я думаю, что есть способ отсоединить документ от исходного RichTextBox. Похоже, что для того, чтобы отсоединить документ от RichTextBox1, вы должны предоставить RichTextBox1 новый документ. Вы не можете установить RichTextBox1.Document в ноль, но вы МОЖЕТЕ установить RichTextBox1.Document в новый FlowDocument (), и я считаю, что это будет работать. Я не могу проверить это прямо сейчас, но я видел, что это было рекомендовано в последнем сообщении этой ветки форума MSDN:

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

0 голосов
/ 08 апреля 2009

Если в данный момент времени в интерфейсе отображается только один редактор, я думаю, что можно синхронизировать содержимое всех редакторов в событии LostFocus активного редактора.

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

РЕДАКТИРОВАТЬ: Я думаю, я не понимаю, почему вы не можете выполнить последовательность XamlWriter.Save / XamlReader.Parse при перемещении между страницами в мастере, но ... как насчет того же экземпляра RichTextBox и переопределять его в контейнере на каждой странице, когда эта страница станет видимой / активной?

...