在多个RichTextBox之间共享FlowDocuments

时间:2009-04-08 11:47:41

标签: wpf flowdocument

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

使用MemoryStreamXamlReader / Writer无法在此处使用,因为我们希望保留单个文档并在任何地方反映更改,因此每次复制都是如此进行。

还有其他可行的方法来实现吗?你可以用什么来创建FlowDocument左右的基础模型?

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

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

4 个答案:

答案 0 :(得分: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 :(得分:0)

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

如果一个编辑器中的更改需要立即反映在应用程序的另一个当前可见部分中,您可以使用Rectangle伪造它,例如,Fill是一个引用活动编辑器的VisualBrush,而Rectangle的宽度和高度是绑定到编辑器的实际宽度和高度。棘手的部分是以相对无缝的方式处理活动编辑器开关。

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

答案 2 :(得分:0)

根据构建向导的方式,我实际上 建议您只需将RichTextBox从一个页面移动到另一个页面。 WPF控件可以随意“取消配置”和“重新配置”,因此只需在整个向导中共享的上下文中使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

答案 3 :(得分:0)

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

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