patterncsharpMinor
Saving a collection of WPF user control layout into an XPS document
Viewed 0 times
xpscontrolwpfuserintocollectionlayoutdocumentsaving
Problem
I am making an application to save a layout of user control into an .xps document. But, the export doesn't seem completed if the data is too many. I've tried to encapsulate each part with
How can I optimize the below code properly to wait for each process to be finished before moving on to the next one, so saving to XPS document will be properly loaded?
P.S. This doesn't happen if the data is not too large.
```
public class MyClass
{
public static void CreatePortableFile(List myViewModels, string path)
{
List views = new List();
List fixedPages = new List();
List pageContents = new List();
FixedDocument fixedDoc = new FixedDocument();
Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
{
foreach (MyViewModelVM item in myViewModels)
{
views.Add(new MyViewV() { DataContext = item });
}
Console.WriteLine("Setting datacontext " + DateTime.Now.TimeOfDay);
}), DispatcherPriority.Loaded);
Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
{
foreach (MyViewV item in views)
{
FixedPage newFixedPage = new FixedPage();
newFixedPage.Children.Add(item);
fixedPages.Add(newFixedPage);
}
Console.WriteLine("Setting fixedpage " + DateTime.Now.TimeOfDay);
}), DispatcherPriority.Loaded);
Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
{
foreach (FixedPage item in fixedPages)
{
PageContent newPageContent = new PageContent();
((System.Windows.Markup.IAddChild)newPageContent).AddChild(item);
pageConten
DispatcherPriority.Loaded but it seems the data binding is horrifyingly take too long to be finished (I honestly don't know what is the problem to be exact).How can I optimize the below code properly to wait for each process to be finished before moving on to the next one, so saving to XPS document will be properly loaded?
P.S. This doesn't happen if the data is not too large.
```
public class MyClass
{
public static void CreatePortableFile(List myViewModels, string path)
{
List views = new List();
List fixedPages = new List();
List pageContents = new List();
FixedDocument fixedDoc = new FixedDocument();
Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
{
foreach (MyViewModelVM item in myViewModels)
{
views.Add(new MyViewV() { DataContext = item });
}
Console.WriteLine("Setting datacontext " + DateTime.Now.TimeOfDay);
}), DispatcherPriority.Loaded);
Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
{
foreach (MyViewV item in views)
{
FixedPage newFixedPage = new FixedPage();
newFixedPage.Children.Add(item);
fixedPages.Add(newFixedPage);
}
Console.WriteLine("Setting fixedpage " + DateTime.Now.TimeOfDay);
}), DispatcherPriority.Loaded);
Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
{
foreach (FixedPage item in fixedPages)
{
PageContent newPageContent = new PageContent();
((System.Windows.Markup.IAddChild)newPageContent).AddChild(item);
pageConten
Solution
I don't really see the sense of splitting this into different sections. Also some of them only add overhead which isn't needed at all.
For each
This can be simplified to
EDIT After reading the comment, I digged a little bit more into this. As this is similiar to printing with datacontext this should fix the issue:
A detailed explaination can be found here
For each
MyViewModelVM in List you are creating a MyViewV with it as DataContext which is in the next loop added as a child to a FixedPage which then is added as a child to a PageContent which is then added to the Pages of the FixedDocument. This can be simplified to
public static void CreatePortableFile(List myViewModels, string path)
{
Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
{
FixedDocument fixedDoc = new FixedDocument();
foreach (MyViewModelVM item in myViewModels)
{
MyViewV view = new MyViewV() { DataContext = item };
FixedPage newFixedPage = new FixedPage();
newFixedPage.Children.Add(view);
PageContent newPageContent = new PageContent();
((System.Windows.Markup.IAddChild)newPageContent).AddChild(newFixedPage);
pageContents.Add(newPageContent);
fixedDoc.Pages.Add(newPageContent);
}
WriteToXps(path, fixedDoc)
}), DispatcherPriority.Loaded);
}EDIT After reading the comment, I digged a little bit more into this. As this is similiar to printing with datacontext this should fix the issue:
public static void CreatePortableFile(List myViewModels, string path)
{
FixedDocument fixedDoc = new FixedDocument();
foreach (MyViewModelVM item in myViewModels)
{
MyViewV view = new MyViewV() { DataContext = item };
FixedPage newFixedPage = new FixedPage();
newFixedPage.Children.Add(view);
PageContent newPageContent = new PageContent();
((System.Windows.Markup.IAddChild)newPageContent).AddChild(newFixedPage);
pageContents.Add(newPageContent);
fixedDoc.Pages.Add(newPageContent);
}
Dispatcher.CurrentDispatcher.Invoke (new Action (delegate { }), DispatcherPriority.ApplicationIdle, null);
WriteToXps(path, fixedDoc)
}A detailed explaination can be found here
Code Snippets
public static void CreatePortableFile(List<MyViewModelVM> myViewModels, string path)
{
Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
{
FixedDocument fixedDoc = new FixedDocument();
foreach (MyViewModelVM item in myViewModels)
{
MyViewV view = new MyViewV() { DataContext = item };
FixedPage newFixedPage = new FixedPage();
newFixedPage.Children.Add(view);
PageContent newPageContent = new PageContent();
((System.Windows.Markup.IAddChild)newPageContent).AddChild(newFixedPage);
pageContents.Add(newPageContent);
fixedDoc.Pages.Add(newPageContent);
}
WriteToXps(path, fixedDoc)
}), DispatcherPriority.Loaded);
}public static void CreatePortableFile(List<MyViewModelVM> myViewModels, string path)
{
FixedDocument fixedDoc = new FixedDocument();
foreach (MyViewModelVM item in myViewModels)
{
MyViewV view = new MyViewV() { DataContext = item };
FixedPage newFixedPage = new FixedPage();
newFixedPage.Children.Add(view);
PageContent newPageContent = new PageContent();
((System.Windows.Markup.IAddChild)newPageContent).AddChild(newFixedPage);
pageContents.Add(newPageContent);
fixedDoc.Pages.Add(newPageContent);
}
Dispatcher.CurrentDispatcher.Invoke (new Action (delegate { }), DispatcherPriority.ApplicationIdle, null);
WriteToXps(path, fixedDoc)
}Context
StackExchange Code Review Q#71081, answer score: 4
Revisions (0)
No revisions yet.