2009-04-08 5 views
2

Un WPF FlowDocument ne peut appartenir qu'à un seul RichTextBox. Cependant, nous aimerions utiliser un seul document qui peut être manipulé à différents points (dans l'espace et le temps) dans l'interface utilisateur. Il n'arrivera jamais qu'il y ait deux RichTextBoxes simultanément affichant un seul document (et ne peut pas, parce que WPF se plaindra). L'utilisation d'un MemoryStream et XamlReader/Writer ne fonctionnera pas ici car nous souhaitons conserver un document unique et refléter les modifications quel que soit l'endroit où il est utilisé, afin de le copier à chaque fois que vous le sortez.Partage de FlowDocuments entre plusieurs RichTextBoxes

Existe-t-il un autre moyen viable d'atteindre cet objectif? Quelque chose que vous pourriez utiliser comme modèle sous-jacent à partir de laquelle créer FlowDocument s ou plus?

Clarification: Les RichTextBox utilisant le document ne sont plus visibles ou ne se trouvent nulle part dans l'arborescence logique/visuelle lorsqu'un autre sera instancié. Bien que je ne puisse probablement pas faire valoir qu'ils ont déjà été mangés par le GC. Apparemment cela cause un problème lors de la réutilisation du document immédiatement après avoir supprimé le RichTextBox de la fenêtre; cela génère toujours une exception que le document est déjà utilisé dans un autre contrôle. Fondamentalement, vous devez avoir un ensemble de "pages d'assistant" qui s'affichent les unes après les autres et il peut arriver que nous réutilisions le document sur deux "pages" successives, mais que nous instancions une nouvelle RTBox à chaque fois. Peut-être qu'il y a un problème ou un meilleur moyen?

Répondre

0

En fonction de la façon dont votre assistant est construit, en réalité vous recommandons de simplement déplacer le RichTextBox de page en page. Les contrôles WPF peuvent être «sans paraphe» et «reparent» à volonté, il suffit donc de rendre l'instance RichTextBox disponible dans le contexte partagé dans votre assistant et assurez-vous de ne pas être réparé/réparé lorsque vous passez d'une page à l'autre. Cela a également l'avantage de sauvegarder tous les styles ou changements d'état des éditeurs sur les pages de l'assistant (ce qui est probablement souhaitable).

S'il n'est pas possible de partager l'instance RichTextBox sur plusieurs pages, je pense qu'il existe un moyen de dissocier le document de la zone RichTextBox d'origine. Il semble que pour dissocier le document de RichTextBox1, vous devez fournir à RichTextBox1 un nouveau document. Vous ne pouvez pas définir RichTextBox1.Document à null, mais vous pouvez définir RichTextBox1.Document à nouveau FlowDocument() et je crois que cela fonctionnera. Je ne suis pas en mesure de tester ce moment, mais je l'ai vu a été recommandé dans le dernier message de ce fil de discussion MSDN:

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

0

Si un seul éditeur est visible dans l'interface à un moment donné, je pense qu'il serait possible de synchroniser le contenu de tous les éditeurs dans l'événement LostFocus de l'éditeur actif. Si les modifications d'un éditeur doivent être reflétées immédiatement dans une autre partie visible de l'application, vous pouvez truquer en utilisant un rectangle, par exemple, où le remplissage est un VisualBrush référençant l'éditeur actif et la largeur et la hauteur du Rectangle étaient liés à la largeur et la hauteur réelles de l'éditeur. La partie délicate serait de gérer le commutateur de l'éditeur actif d'une manière relativement transparente.

EDIT: Je suppose que je ne comprends pas pourquoi vous ne pouvez pas faire une XamlWriter.Save/séquence XamlReader.Parse lors du déplacement entre les pages de l'assistant, mais ... sur l'utilisation de la même instance RichTextBox tout le temps et re-parent à un conteneur dans chaque page lorsque cette page devient visible/active?

+0

J'ai élaboré un peu plus dans la question. Nous n'avons pas besoin de refléter ces changements immédiatement ailleurs dans l'interface utilisateur. Mais un document résiste à être utilisé plus d'une fois, apparemment, ce qui peut être contourné avec XamlWriter/Reader pour le contenu statique, mais pas pour les trucs dynamiques :( – Joey

4

Le FlowDocument ne peut pas être partagée par plusieurs contrôles RichTextBox directement ..

Vous avez donc besoin de 'détacher' ce document premier ...

Alors

RTB2.Document = RTB1.Document; 

ne fonctionnera pas et entraînera votre exception ..

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

fonctionnera comme un charme ...

Mon échantillon de code:

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 derrière ..

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

Son pas la plus jolie dans le livre, mais il fonctionne ...

Hope this helps ..

+1

Je viens d'utiliser ce code et c'était génial 'Private Sub TradeTextBoxDocument (ByRef Comme la source RichTextBox, destination ByRef Comme RichTextBox) de flux Dim Comme FlowDocument = source.Document source.Document = Nouveau FlowDocument destination.Document = débit End Sub » – DoomVroom

0

flux Le document ne peut pas être partagé, vous devez donc le détacher.

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

ce n'est pas détacher, c'est sérialisation et désérialisation. Prenez note que je dirigeais cette approche dans la question (il y a environ six ans). – Joey

Questions connexes