2

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

在这里使用MemoryStreamand XamlReader/Writer将不起作用,因为我们希望保留单个文档并在使用它的任何地方反映更改,因此每次都复制它已经过时了。

有没有其他可行的方法来实现这一目标?您可以将其用作创建FlowDocuments 的基础模型吗?

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

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

4

4 回答 4

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;

会像魅力一样工作......

我的代码示例:

xml:

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

它不是书中最漂亮的,但它确实有效......

希望这可以帮助..

于 2009-04-16T08:09:29.140 回答
0

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

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

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

于 2009-04-08T14:01:29.870 回答
0

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

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

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

于 2009-04-15T16:11:50.427 回答
0

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

string flowDocument = XamlWriter.Save(RTF1.Document);
RichTextBox RTF2= new RichTextBox();
RTF2.Document = XamlReader.Load(new MemoryStream(Encoding.Default.GetBytes(flowDocument))) as FlowDocument; 
于 2015-05-13T03:48:04.400 回答