【问题标题】:Failed to correctly exports wpf view to xps if the data is "too many"如果数据“太多”,则无法将 wpf 视图正确导出到 xps
【发布时间】:2014-11-21 06:22:08
【问题描述】:

问题


所以,我正在构建我的应用程序,以便可以将其视图导出到 Xps 文档中。该应用程序实际上只是UserControlItemsControl

在我向ItemsControl 添加更多数据之前,它工作正常,导出的文件只是显示一个“未完成”的加载视图。

这是我的导出到 xps 代码:

    public static void CreatePortableFile(List<N_SheetPageVM> numberedSheetPages, string path)
    {
        List<N_SheetPageV> sheetPages = new List<N_SheetPageV>();
        foreach (N_SheetPageVM item in numberedSheetPages)
        {
            N_SheetPageV temp = new N_SheetPageV();
            temp.DataContext = item;
            sheetPages.Add(temp);
        }

        List<FixedPage> fixedPages = new List<FixedPage>();
        foreach (N_SheetPageV item in sheetPages)
        {
            FixedPage newFixedPage = new FixedPage();
            newFixedPage.Children.Add(item);
            fixedPages.Add(newFixedPage);
        }

        List<PageContent> pageContents = new List<PageContent>();
        foreach (FixedPage item in fixedPages)
        {
            PageContent newPageContent = new PageContent();
            ((System.Windows.Markup.IAddChild)newPageContent).AddChild(item);
            pageContents.Add(newPageContent);
        }

        FixedDocument fixedDoc = new FixedDocument();
        foreach (PageContent item in pageContents)
        {
            fixedDoc.Pages.Add(item);
        }

        XpsDocument xpsDoc = new XpsDocument(path, FileAccess.Write);
        XpsDocumentWriter xWriter = XpsDocument.CreateXpsDocumentWriter(xpsDoc);
        xWriter.Write(fixedDoc);
        xpsDoc.Close();
    }

    public static void CreatePortableFile(List<S_SheetPageVM> stavedSheetPages, string path)
    {
        List<S_SheetPageV> sheetPages = new List<S_SheetPageV>();
        foreach (S_SheetPageVM item in stavedSheetPages)
        {
            sheetPages.Add(new S_SheetPageV() { DataContext = item });
        }

        List<FixedPage> fixedPages = new List<FixedPage>();
        foreach (S_SheetPageV item in sheetPages)
        {
            FixedPage newFixedPage = new FixedPage();
            newFixedPage.Children.Add(item);
            fixedPages.Add(newFixedPage);
        }

        List<PageContent> pageContents = new List<PageContent>();
        foreach (FixedPage item in fixedPages)
        {
            PageContent newPageContent = new PageContent();
            ((System.Windows.Markup.IAddChild)newPageContent).AddChild(item);
            pageContents.Add(newPageContent);
        }

        FixedDocument fixedDoc = new FixedDocument();
        foreach (PageContent item in pageContents)
        {
            fixedDoc.Pages.Add(item);
        }

        XpsDocument xpsDoc = new XpsDocument(path, FileAccess.Write);
        XpsDocumentWriter xWriter = XpsDocument.CreateXpsDocumentWriter(xpsDoc);
        xWriter.Write(fixedDoc);
        xpsDoc.Close();
    }

屏幕截图


1.小数据截图 下面的截图显示,如果数据很小,那么它正确导出到 xps :

2。意外的大数据屏幕截图 下面的屏幕截图显示,如果数据“大”,那么它错误地导出到 xps 中:

3.预期的大数据屏幕截图(导出前拍摄) 这是“大”数据的预期输出(从应用程序截取的屏幕截图,预导出,因为导出无法正常运行)

附加细节


  1. 实际上,即使只是应用程序中的普通“加载”,屏幕上显示的第一件事就是屏幕截图#2,然后显示#3。这就是为什么我猜是加载问题。
  2. 我检查了加载方法(每个类为 1),即:清除视图模型数据,然后将模型重新分配到它的视图模型中。并且拨打的号码是正确的,所以不会重复拨打。
  3. 如果您需要自己查看,那么我提供了意外和预期输入和输出文件的下载链接,以及 .exe here
  4. 为什么我引用“太多”或“很多”?因为我觉得太多了。
  5. 没有异步方法。
  6. 如果需要,您可以申请实际的 C# 项目。
  7. 页面排列由用户手动完成(在最后一个页面之后添加或删除新页面),由一些类似于 PageVM 的集合处理。
  8. 不需要完整的 MVVM 方法。

我预测解决方案会是什么样子


也许解决方案会在某种程度上延迟导出过程以等待加载完成(即使它们实际上都是同步过程,在这个项目中没有异步)

附:如果你需要完整的源代码,我很乐意在私人房间里分享给你。

谢谢。

【问题讨论】:

  • 你能帮我试一试吗?将行从XpsDocument xpsDoc = ... 向前移动到一个匿名方法中,并通过Dispatcher.Invoke 使用DispatcherPriorityLoaded 运行它。看看这是否有什么不同。
  • @MikeStrobel 神圣!有用!!你能在答案中完全解释这种行为吗?我想知道为什么!谢谢!

标签: c# wpf export xpsdocument


【解决方案1】:

我注意到您正在将DataContext 设置在要放置在文档中的项目上。这表明内容包含绑定,在这种情况下,问题很可能是在您导出文档时绑定目标尚未更新。

数据绑定在DispatcherPriorityDataBind(级别8)处处理。为了确保在您导出文档时数据实际可用,您需要安排在处理完绑定后进行导出。您还想确保您的内容已经过布局。您可以通过将导出安排在 DispatcherPriority.Loaded(级别 6)来完成这两个操作,该导出在 DataBind 之后运行,并且与布局具有相同的优先级。

尝试如下更新您的导出方法:

List<N_SheetPageV> sheetPages = new List<N_SheetPageV>();
foreach (N_SheetPageVM item in numberedSheetPages)
{
    N_SheetPageV temp = new N_SheetPageV();
    temp.DataContext = item;
    sheetPages.Add(temp);
}

...

Dispatcher.CurrentDispatcher.Invoke(
    DispatcherPriority.Loaded,
    new Action(
        () =>
        {
            XpsDocument xpsDoc = new XpsDocument(path, FileAccess.Write);
            XpsDocumentWriter xWriter = XpsDocument.CreateXpsDocumentWriter(xpsDoc);
            xWriter.Write(fixedDoc);
            xpsDoc.Close();
        })
    );

【讨论】:

  • 嗨,迈克,我向其中添加了更多数据,再次感觉像是意外的数据截图。我试图降低优先级,但似乎效果不佳..有什么想法吗?谢谢。
【解决方案2】:

如果有人遇到和我一样的问题,请用这个,这解决了我的问题:

public static void CreatePortableFile(List<MyViewModelVM> myViewModels, string path)
{

    FixedDocument fixedDoc = new FixedDocument();

    foreach (MyViewModelVM item in myViewModels)
    {
        //idem
    }

    DocumentViewer dummy = new DocumentViewer(); //it's the key
    dummy.Document = fixedDoc; //it's the key

    Dispatcher.CurrentDispatcher.Invoke (new Action (delegate { }), DispatcherPriority.ApplicationIdle, null);

    WriteToXps(path, fixedDoc)
}   

希望它可以帮助那里的人。 (如果有人可以解释这种行为,那就太好了,因为我没有)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 1970-01-01
    • 2011-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-13
    相关资源
    最近更新 更多