Reputation: 7211
I have a bit of a chicken-and-egg problem here...
I want to print map data that is retrieved asynchronously from a web service. The problem is I don't know the selected paper size (which affects the size of the map I need to request from the service) until the user presses OK on the print dialog and the PrintPage event is fired.
The only thing I can think of is to somehow "pause" the entire printing process in the middle of the PrintPage event, retrieve the map image, set the current page's PageVisual to the map image, and then let the printing process continue. But this does not seem either possible or "correct".
I thought of having the user select a page size from a combo box before printing (that way I could retrieve the proper image size and enable the "print" button only after all the map data is retrieved). But then the user would need to select the page size twice, once from my combo box and once from the print dialog. If they selected 11x17 from the combo box and then just banged OK on the print dialog (which is very likely), it would print an 11x17 layout to the default 8.5x11 paper size.
The only other mention of this problem I found is http://betaforums.silverlight.net/forums/p/192371/444897.aspx, and they didn't find a solution either.
Upvotes: 2
Views: 1240
Reputation: 5584
You can defer printing like this:
void p_PrintPage(object sender, PrintPageEventArgs e)
{
if (isLoadedMap())
{
e.PageVisual = null;
e.HasMorePages = true;
} else {
e
}
}
Upvotes: 1
Reputation: 189555
There is no direct solution to this problem. The print engine is in charge here and demands a visual for the next page. A better model from the developers point of view would have been to invert the events into methods and have the code call PrintPage
. I'm sure there are intractable technical reasons why that couldn't have been done.
As I see it you have two choices. One is to simply block the thread with a WaitHandle
in the PrintPage
event while you wait for the asynchronous operation to complete. I can't believe I'm saying that but in this case its reasonable viable. Something like:-
using(var waitHandle = new AutoResetEvent(false))
{
// Some intial code
var result = YourAsyncOperation(parametersNeeded, () => waitHandle.set());
bool signaled = waitHandle.WaitOne(30000); // 30
// Conitnue as appropriate (result might be indicate an error, signaled might be false indicating a timeout).
}
Your other option is to ensure you have enough data client side for Silverlight code to do the layout work itself.
Upvotes: 1