2 Stimmen

Gemeinsame Nutzung von FlowDocuments durch mehrere RichTextBoxen

EIN WPF FlowDocument kann nur zu einem einzigen RichTextBox . Wir möchten jedoch ein einziges Dokument verwenden, das an verschiedenen Stellen (in Raum und Zeit) in der Benutzeroberfläche bearbeitet werden kann. Es wird nie passieren, dass es zwei RichTextBoxes gleichzeitig ein einzelnes Dokument anzeigen (und kann es nicht, weil WPF sich beschweren wird).

Mit einer MemoryStream y XamlReader / Writer wird hier nicht funktionieren, da wir ein einziges Dokument beibehalten und Änderungen überall widerspiegeln möchten, wo es verwendet wird, daher ist es nicht möglich, es jedes Mal zu kopieren.

Gibt es einen anderen gangbaren Weg, dies zu erreichen? Etwas, das Sie als zugrundeliegendes Modell verwenden könnten, um daraus FlowDocument s oder so?

Klärung: Die RichTextBoxen, die das Dokument verwenden, sind nicht mehr sichtbar oder irgendwo im logischen/visuellen Baum, wenn eine andere instanziiert wird. Obwohl ich wahrscheinlich nicht erzwingen kann, dass sie bereits von der GC gegessen wurden. Anscheinend führt dies zu einem Problem, wenn das Dokument unmittelbar nach dem Entfernen der RichTextBox aus dem Fenster wiederverwendet wird; das wirft immer noch eine Ausnahme, dass das Dokument bereits in einem anderen Steuerelement verwendet wird.

Im Grunde haben wir eine Reihe von "Assistentenseiten", die nacheinander angezeigt werden, und es kann vorkommen, dass wir das Dokument auf zwei aufeinander folgenden "Seiten" wiederverwenden, aber jedes Mal eine neue RTBox instanziieren. Gibt es vielleicht ein Problem oder einen besseren Weg?

4voto

Arcturus Punkte 26057

Das FlowDocument kann nicht von mehreren RichTextBox-Steuerungen direkt gemeinsam genutzt werden

Sie müssen das Dokument also zuerst "abtrennen"...

Also

RTB2.Document = RTB1.Document;

wird nicht funktionieren und zu einer Ausnahme führen.

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

funktioniert wie ein Zauber...

Mein Code-Beispiel:

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>

Code hinter

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

Es ist nicht das Schönste im Buch, aber es funktioniert...

Ich hoffe, das hilft

0voto

Daniel Pratt Punkte 11859

Wenn immer nur ein Editor in der Oberfläche sichtbar ist, sollte es doch möglich sein, die Inhalte aller Editoren im LostFocus-Ereignis des aktiven Editors zu synchronisieren.

Wenn Änderungen in einem Editor sofort in einem anderen, gerade sichtbaren Teil der Anwendung widergespiegelt werden müssen, könnte man dies z.B. mit einem Rectangle vortäuschen, wobei die Füllung ein VisualBrush ist, das auf den aktiven Editor verweist, und die Breite und Höhe des Rectangles an die tatsächliche Breite und Höhe des Editors gebunden ist. Der knifflige Teil wäre die Handhabung des aktiven Editors Schalter in einer relativ nahtlosen Art und Weise.

EDIT : Ich schätze, ich verstehe nicht, warum Sie nicht eine XamlWriter.Save / XamlReader.Parse-Sequenz tun können, wenn Sie zwischen Seiten im Assistenten bewegen, aber ... was über die Verwendung der gleichen RichTextBox-Instanz die ganze Zeit und re-parent es zu einem Container in jeder Seite, wenn diese Seite sichtbar/aktiv wird?

0voto

Jared Bienz - MSFT Punkte 3540

Je nachdem, wie Ihr Assistent aufgebaut ist, habe ich eigentlich würde empfehlen, dass Sie die RichTextBox einfach von Seite zu Seite verschieben. WPF-Steuerelemente können nach Belieben "entparentiert" und "reparentiert" werden. Machen Sie also einfach die RichTextBox-Instanz im Kontext verfügbar, der in Ihrem Assistenten gemeinsam genutzt wird, und stellen Sie sicher, dass Sie die Parentierung aufheben bzw. reparieren, wenn Sie von Seite zu Seite wechseln. Dies hat auch den Vorteil, dass alle Stile oder Änderungen am Status des Editors auf allen Seiten des Assistenten gespeichert werden (was wahrscheinlich wünschenswert ist).

Wenn es nicht möglich ist, die RichTextBox-Instanz seitenübergreifend zu nutzen, gibt es meiner Meinung nach eine Möglichkeit, das Dokument von der ursprünglichen RichTextBox zu trennen. Um das Dokument von RichTextBox1 zu trennen, müssen Sie RichTextBox1 mit einem neuen Dokument versehen. Sie können RichTextBox1.Document nicht auf null setzen, aber Sie KÖNNEN RichTextBox1.Document auf new FlowDocument() setzen und ich glaube, das wird funktionieren. Ich bin im Moment nicht in der Lage, dies zu testen, aber ich habe gesehen, dass es im letzten Beitrag dieses MSDN-Forum-Threads empfohlen wurde:

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

0voto

sam Punkte 141

Flussdokumente können nicht geteilt werden, daher müssen Sie sie abtrennen.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X