Exception: BitmapFrameDecode must have IsFrozen set to false to modify

1.5k views Asked by At

I have a program written in C# WPF to print documents automatically. One of the features it has is it can detect image download failure so the document which has that empty image doesn't get printed.

This is one part of the code to detect download failure of 'sender logo' image:

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

When the event handler BitmapFrameDownloadFailed from _senderLogoFrame.DownloadFailed is invoked, this exception is occurred:

shippingLabelForm.CreateDocument Exception: Specified value of type 'System.Windows.Media.Imaging.BitmapFrameDecode' must have IsFrozen set to false to modify. Stack Trace: at System.Windows.Freezable.WritePreamble() at System.Windows.Media.Imaging.BitmapSource.add_DownloadFailed(EventHandler`1 value) at InvoicePrintingClient.Form.ShippingLabelForm.SetDataToElements() at InvoicePrintingClient.Form.ShippingLabelForm.d__18.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at InvoicePrintingClient.Main.PrintClientMainWindow.<>c__DisplayClass101_1.<b__4>d.MoveNext()

What does it mean by setting IsFrozen to false? Does it have anything to do with the BitmapSource.DownloadFailure event handler? What do I have to do to resolve this problem?

1

There are 1 answers

0
Clemens On BEST ANSWER

When you call BitmapFrame.Create with a Stream or local file Uri as parameter (and it can therefore immediately decode a bitmap), the method returns a frozen BitmapFrame.

From MSDN:

Any BitmapFrame returned from a decoder is always frozen. If you require a modifiable copy, you must first create a copy of the BitmapFrame by using the Clone method.

So you can't modify the BitmapFrame, for example by attaching a handler for the DownloadFailed event.

Before attaching the event handler, simply check the IsFrozen and IsDownloading properties. Attaching a DownloadFailed event handler is pointless anyway if is IsDownloading is false.

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

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

SenderLogo.Source = _senderLogoFrame;

For checking if a local file Uri points to a potentially invalid or nonexisting image file, put the BitmapFrame.Create call in a try/catch block,