从Silverlight 4打印异步数据
我这里有点鸡和蛋的问题 我想打印从web服务异步检索的地图数据。问题是,在用户在“打印”对话框上按“确定”并触发PrintPage事件之前,我不知道所选的纸张大小(这会影响我需要从服务请求的地图大小) 我唯一能想到的是在打印页面事件的中间“暂停”整个打印过程,检索地图图像,将当前页面的PageVisual设置到地图图像,然后让打印过程继续。但这似乎既不可能也不“正确” 我想让用户在打印之前从组合框中选择一个页面大小(这样我就可以检索到正确的图像大小,并且只有在检索到所有地图数据后才能启用“打印”按钮)。但是用户需要两次选择页面大小,一次从我的组合框中选择,一次从打印对话框中选择。如果他们从组合框中选择11x17,然后在“打印”对话框上单击“确定”(很可能),则会将11x17布局打印为默认的8.5x11纸张大小从Silverlight 4打印异步数据,silverlight,silverlight-4.0,asynchronous,printing,Silverlight,Silverlight 4.0,Asynchronous,Printing,我这里有点鸡和蛋的问题 我想打印从web服务异步检索的地图数据。问题是,在用户在“打印”对话框上按“确定”并触发PrintPage事件之前,我不知道所选的纸张大小(这会影响我需要从服务请求的地图大小) 我唯一能想到的是在打印页面事件的中间“暂停”整个打印过程,检索地图图像,将当前页面的PageVisual设置到地图图像,然后让打印过程继续。但这似乎既不可能也不“正确” 我想让用户在打印之前从组合框中选择一个页面大小(这样我就可以检索到正确的图像大小,并且只有在检索到所有地图数据后才能启用“打印”
关于这个问题,我唯一提到的是,他们也没有找到解决办法。这个问题没有直接的解决办法。打印引擎在这里负责,需要下一页的视觉效果。从开发人员的角度来看,更好的模型应该是将事件转化为方法,并让代码调用
PrintPage
。我敢肯定,有一些难以解决的技术原因导致这一切无法实现
在我看来,你有两个选择。一种是在等待异步操作完成时,在PrintPage
事件中使用WaitHandle
简单地阻塞线程。我不敢相信我这么说,但在这种情况下,这是合理可行的。比如:-
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).
}
您的另一个选择是确保有足够的数据客户端供Silverlight代码自行进行布局工作。您可以按如下方式推迟打印:
void p_PrintPage(object sender, PrintPageEventArgs e)
{
if (isLoadedMap())
{
e.PageVisual = null;
e.HasMorePages = true;
} else {
e
}
}
这似乎更像是一个用户体验问题,而不是一个技术问题——你真的想自动输出打印作业吗?这可能很无聊,但如果你像其他应用程序一样等待用户启动打印作业,不是更好吗;他们按下一个按钮,操作系统的打印对话框就会出现。问题是Silverlight只允许从用户启动的事件打印,因此在检索到映射数据后,我无法在异步事件中稍后打印。这很有效!这并不像你说的那样是一个优雅的解决方案,但是如果Silverlight限制我在UI线程中打印,并且只在最终用户直接触发的事件中打印,那么它就必须这样做。唯一的问题是它在打印时会暂时冻结UI(因为线程被阻塞),但我可以接受。在打印期间,UI几乎被阻塞:->