1

我有一个用 C# WPF 编写的程序来自动打印文档。它具有的功能之一是它可以检测图像下载失败,因此具有该空图像的文档不会被打印。

这是检测“发件人徽标”图像下载失败的代码的一部分:

_senderLogoFrame = BitmapFrame.Create(new Uri(_invoice.Sender.Logo));
_senderLogoFrame.DownloadFailed += BitmapFrameDownloadFailed;
SenderLogo.Source = _senderLogoFrame;

当调用事件处理程序BitmapFrameDownloadFailed_senderLogoFrame.DownloadFailed,会发生此异常:

shippingLabelForm.CreateDocument 异常:“System.Windows.Media.Imaging.BitmapFrameDecode”类型的指定值必须将 IsFrozen 设置为 false 才能修改。堆栈跟踪:在 InvoicePrintingClient.Form.ShippingLabelForm.SetDataToElements() 的 InvoicePrintingClient.Form.ShippingLabelForm.d__18 的 System.Windows.Media.Imaging.BitmapSource.add_DownloadFailed(EventHandler`1 value) 的 System.Windows.Freezable.WritePreamble()。 MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 在 InvoicePrintingClient 的 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) .Main.PrintClientMainWindow.<>c__DisplayClass101_1.<b__4>d.MoveNext()

IsFrozen设置为false是什么意思?它与BitmapSource.DownloadFailure事件处理程序有什么关系吗?我该怎么做才能解决这个问题?

4

1 回答 1

1

当您BitmapFrame.Create使用 Stream 或本地文件 Uri 作为参数调用时(因此它可以立即解码位图),该方法返回一个冻结的 BitmapFrame。

来自MSDN

从解码器返回的任何 BitmapFrame 总是被冻结。如果需要可修改的副本,则必须首先使用 Clone 方法创建 BitmapFrame 的副本。

因此,您不能修改 BitmapFrame,例如通过附加DownloadFailed事件处理程序。

在附加事件处理程序之前,只需检查IsFrozenIsDownloading属性。IsDownloading如果 is为假,那么附加 DownloadFailed 事件处理程序毫无意义。

_senderLogoFrame = BitmapFrame.Create(new Uri(_invoice.Sender.Logo));

if (!_senderLogoFrame.IsFrozen && _senderLogoFrame.IsDownloading)
{
    _senderLogoFrame.DownloadFailed += BitmapFrameDownloadFailed;
}

SenderLogo.Source = _senderLogoFrame;

要检查本地文件 Uri 是否指向可能无效或不存在的图像文件,请将BitmapFrame.Create调用放在一个try/catch块中,

于 2017-12-13T07:12:33.193 回答