WPF 固定文档动态数据

本文关键字:动态 数据 文档 WPF | 更新日期: 2023-09-27 18:30:45

我正在创建FixedDocument并动态添加页面。

public partial class Window1 : Window
{
    FixedDocument fd = new FixedDocument();
    TextBlock page1Text = new TextBlock();
    public Window1()
    {
        InitializeComponent();
    }
    private void Print_Click(object sender, RoutedEventArgs e)
    {
        PrintDialog pd = new PrintDialog();

        fd.DocumentPaginator.PageSize = new Size(pd.PrintableAreaWidth, pd.PrintableAreaHeight);
        for (int i = 0; i <= 5; i++)
        {
            FixedPage page1 = new FixedPage();
            page1.Width = fd.DocumentPaginator.PageSize.Width;
            page1.Height = fd.DocumentPaginator.PageSize.Height;
            pages();
            page1.Children.Add(page1Text);
            PageContent page1Content = new PageContent();
            ((IAddChild)page1Content).AddChild(page1);
            fd.Pages.Add(page1Content);
        }
        DocumentViewer dr = new DocumentViewer();
        dr.Height = 700;
        dr.Document =fd;
        stack.Children.Add(dr);

    }
    private void pages()
    {
        page1Text.Text = "This is a test";
        page1Text.FontSize = 40;
        page1Text.Margin = new Thickness(96);
    }
}

代码仍然给出错误,指出 page1content 是另一个父级的子项。

WPF 固定文档动态数据

这是一个很容易诊断的错误; 视觉对象只能有一个父项,否则您将VisualTree中具有循环依赖项。查看代码以检查是否两次使用相同的视觉对象。

如果希望视觉对象同时出现在两个位置,则需要复制它;如果第二次使用是有意的,则可以通过将自身从父视觉对象中删除自身来取消父视觉对象,例如 ( canvas.Parent.Remove(canvas) )。

在发布的代码示例中,我可以确定至少一个发生这种情况的实例,并在下面详细介绍。


您将vCanvas实例添加到while(loop)块中的多个实例。您需要为每个迭代创建一个新Canvas

var visual = /* unknown */;
var fd = new FixedDocument();   
while(loop)
{
    var canvas = PageInit();
    var page = new FixedPage();
    page.Width = visual.DocumentPaginator.PageSize.Width;
    page.Height = visual.DocumentPaginator.PageSize.Height;
    page.Children.Add(canvas);
    PageContent pageContent = new PageContent();
    ((IAddChild)pageContent).AddChild(page);
    visual.Pages.Add(pageContent);
}

出于此示例的目的,我将Canvas PageInit()

private Canvas PageInit()
{
    var tb = new TextBlock();
    tb.Text = "From Data";
    var canvas = new Canvas();
    canvas.Children.Add(tb);
    return canvas;
}

我做到了。解决方案如下

private void Print_Click(object sender, RoutedEventArgs e)
    {
        PrintDialog pd = new PrintDialog();

fd.DocumentPaginator.PageSize = new Size(pd.PrintableAreaWidth,fd.PrintableAreaHeight);
        for (int i = 0; i <= 5; i++)
        {
            FixedPage page1 = new FixedPage();
            page1.Width = fd.DocumentPaginator.PageSize.Width;
            page1.Height = fd.DocumentPaginator.PageSize.Height;
            UIElement page1Text = pages();
            page1.Children.Add(page1Text);
            PageContent page1Content = new PageContent();
            ((IAddChild)page1Content).AddChild(page1);
            fd.Pages.Add(page1Content);
        }
        DocumentViewer dr = new DocumentViewer();
        dr.Height = 700;
        dr.Document =fd;
        stack.Children.Add(dr);

    }
    private UIElement pages()
    {
        Canvas pcan = new Canvas();
        TextBlock page1Text = new TextBlock();
        page1Text.Text = "This is a test";
        page1Text.FontSize = 40;
        page1Text.Margin = new Thickness(96);
        pcan.Children.Add(page1Text);

        return pcan;
    }

您可以跳过画布。这是我项目的要求,所以我正在尝试它。