Wpf 在多个RichTextBox之间共享流文档

Wpf 在多个RichTextBox之间共享流文档,wpf,flowdocument,Wpf,Flowdocument,WPFFlowDocument只能属于一个RichTextBox。但是,我们希望使用一个可以在UI中的不同点(空间和时间)操作的文档。永远不会有两个richtextbox同时显示一个文档(而且不能,因为WPF会抱怨) 使用MemoryStream和XamlReader/Writer在这里不起作用,因为我们希望保留一个文档,并在使用它的任何地方反映更改,因此每次都要复制它 有没有其他可行的方法来实现这一点?您可以使用它作为基础模型,从中创建FlowDocuments等等 澄清:当另一个RichTe

WPF
FlowDocument
只能属于一个
RichTextBox
。但是,我们希望使用一个可以在UI中的不同点(空间和时间)操作的文档。永远不会有两个
richtextbox
同时显示一个文档(而且不能,因为WPF会抱怨)

使用
MemoryStream
XamlReader
/
Writer
在这里不起作用,因为我们希望保留一个文档,并在使用它的任何地方反映更改,因此每次都要复制它

有没有其他可行的方法来实现这一点?您可以使用它作为基础模型,从中创建
FlowDocument
s等等

澄清:当另一个RichTextBox将被实例化时,使用该文档的RichTextBox将不再可见或在逻辑/可视树中的任何位置。虽然我可能不能强制他们已经被GC吃掉了。从窗口中删除RichTextBox后立即重新使用文档时,似乎会出现问题;这仍然会引发文档已在另一个控件中使用的异常


基本上,我们有一组一个接一个显示的“向导页面”,我们可以在两个连续的“页面”上重复使用文档,但每次都实例化一个新的RTBox。可能有问题或更好的方法?

如果在任何给定时间界面中只有一个编辑器可见,我认为可以在活动编辑器的LostFocus事件中同步所有编辑器的内容

如果一个编辑器中的更改需要立即反映在应用程序的另一个当前可见部分中,您可以使用一个矩形来伪造它,例如,其中填充是一个引用活动编辑器的可视化笔刷,并且矩形的宽度和高度绑定到编辑器的实际宽度和高度。棘手的部分是以相对无缝的方式处理活动编辑器开关


编辑:我想我不明白为什么在向导中在页面之间移动时不能执行XamlWriter.Save/XamlReader.Parse序列,但是…如果始终使用同一个RichTextBox实例,并在该页面变为可见/活动时将其重新设置为每个页面中的容器的父级呢?

根据向导的构造方式,我建议您只需将RichTextBox从一页移动到另一页。WPF控件可以随意“取消插入”和“重新插入”,因此只需确保RichTextBox实例在整个向导中共享的上下文中可用,并确保在从一页移动到另一页时进行取消插入/重新插入即可。这还有一个好处,就是在向导中跨页面保存对编辑器状态的任何样式或更改(这可能是可取的)

如果无法跨页面共享RichTextBox实例,我认为有一种方法可以将文档与原始RichTextBox解除关联。看起来,为了解除文档与RichTextBox1的关联,您必须向RichTextBox1提供一个新文档。您不能将RichTextBox1.Document设置为null,但可以将RichTextBox1.Document设置为new FlowDocument(),我相信这会起作用。我现在无法测试它,但我在MSDN论坛帖子的最后一篇帖子中看到了它的推荐:


多个RichTextBox控件不能直接共享FlowDocument

因此,您需要先“分离”该文档

所以

不起作用,将导致您的异常

FlowDocument doc = RTB1.Document;
RTB1.Document = new FlowDocument(); //Document cannot be null, so therefor the new FlowDocument instance
RTB2.Document = doc;
会很有魅力的

我的代码示例:

Xaml:

这不是书中最漂亮的,但它很管用


希望这有帮助。

流文档无法共享,因此您必须分离

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

我在这个问题上做了进一步的阐述。我们无需在UI的其他地方立即反映这些更改。但是一个文档似乎不能被多次使用,这可以通过XamlWriter/Reader绕过静态内容,但不能用于动态内容:(这不是分离,而是序列化和反序列化。请注意,我在这个问题中排除了这种方法(大约六年前)。我刚刚使用了这段代码,它非常神奇。'Private Sub-TradeTextBoxDocument(ByRef-source作为RichTextBox,ByRef-destination作为RichTextBox)Dim flow作为FlowDocument=source.Document-source.Document=New FlowDocument-destination.Document=flow End-Sub'
<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;
    }
}
string flowDocument = XamlWriter.Save(RTF1.Document);
RichTextBox RTF2= new RichTextBox();
RTF2.Document = XamlReader.Load(new MemoryStream(Encoding.Default.GetBytes(flowDocument))) as FlowDocument;