0

问题


因此,我正在构建我的应用程序,以便可以将其视图导出到 Xps 文档中。该应用程序实际上只是ItemsControl一个UserControl.

它工作正常,直到我向 中添加更多数据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. UNEXPECTED LARGE DATA SCREENSHOT 下面的截图显示,如果数据是“大”,那么它被错误地导出到 xps :

在此处输入图像描述

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

在此处输入图像描述

附加细节


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

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


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

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

谢谢你。

4

2 回答 2

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();
        })
    );
于 2014-11-24T17:12:58.133 回答
0

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

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

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

于 2014-11-28T17:31:56.683 回答