Cory Nelson Cory Nelson - 2 months ago 18
C# Question

Manually loading framework elements

I've built a templated printing system which creates XPS documents using XAML, via WPF's

CreateVisualsCollator()
:

FrameworkElement fe = ...;

using (Package p = Package.Open(...))
using (XpsDocument doc = new XpsDocument(p))
{
XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
SerializerWriterCollator col = writer.CreateVisualsCollator();

Size size = new Size(page size...)
fe.Measure(size);
fe.Arrange(new Rect(size));
fe.UpdateLayout();

col.Write(fe);
// fe.IsLoaded is still false here!
}


I'm doing this without a UI present -- this is actually destined for a Windows service.

I've been doing hacks like calling
UpdateLayout()
manually to perform sizing, and have realized that the reason I'm having to do so is that the controls are never getting their
Loaded
event triggered, and never getting into a loaded state. I've just hit a snag where this has become a problem and my hack no longer works.

Is there a way to manually trigger a proper load for an element and all its children?

Answer

I've been able to attack this from two angles.

First, don't load up your elements directly. Use a ContentControl, which seems to have a better handle on instantiating templates and resolves a number of deep data binding issues:

new ContentControl
{
    Content = item,
    ContentTemplate = template
}

Next, allow the idle queue to process. This forces various delayed tasks to run that WPF normally queues up for when your window is idle:

FrameworkElement element = ...;
element.Dispatcher.BeginInvoke(() => {}, DispatcherPriority.SystemIdle);