ChainedBitmap Freezing Problems

Dec 29, 2009 at 4:07 PM

Hi, I'm trying to use the ColorKeyBitmap in the 4.0 beta but I ran into some issues with freezing. In particular I want to create the color keyed bitmaps in xaml and not in code:

<Image Source="/objedit;component/Images/VSFolder_closed.bmp" Width="32" Height="32" />
<Image Width="32" Height="32">
    <Image.Source>
        <utils:ColorKeyBitmap TransparentColor="Magenta" Source="/objedit;component/Images/VSFolder_closed.bmp" />
    </Image.Source>
</Image>

I get an exception in ChainedBitmap.OnSourcePropertyChanged which complains that you're trying to modify a frozen object by adding those event listeners. Exception happens if I have the design view open and also if I try to run the project. The exception in the design view is especially nasty because VisualStudio can't seem to recover and becomes unresponsive. If I comment out the code adding the event listeners it seems to work fine, but I suppose it breaks some semantics for downloadable resources.

Second problem is that VisualStudio often is going unresponsive whenever I go into a xaml/designer view containing a BitmapSource subclass, even if there is no exception, and I then have to kill the process. So question: Is your approach of subclassing BitmapSource still usable in 4.0? Or are there any other ways of getting color-keyed image resources into design time?

Dec 30, 2009 at 9:30 AM

On a second note, the hanging issue may or may not be related, I'm also getting them without BitmapSource overloads, just if I use them its hanging much more often. May be just the fact that it's still a beta.

I still would like to know if overloading BitmapSource is going to be a valid approach in 4.0 though, and if it is the freezing issue should be resolved. I'd like to use it for procedurally generated bitmaps (attached to an image brush most likely) and it would be cool to be able to configure/place them at design time and get a preview how they look like.

Coordinator
Mar 10, 2010 at 2:26 AM

Thanks for reporting this issue.  I have checked in a simple fix.

Mar 10, 2010 at 6:29 AM

Thanks for looking into this, it works on 2008, but not on 2010/RC, there I get an ugly NotImplementedException in the designer from above XAML snippet. Though it does work if I just run the project. Any idea on this one? It doesn't seem to come from your code ...

System.NotImplementedException
The method or operation is not implemented.
   at System.Windows.Media.Imaging.BitmapSource.UpdateCachedSettings()
   at System.Windows.Media.Imaging.BitmapSource.set_WicSourceHandle(BitmapSourceSafeMILHandle value)
   at System.Windows.Media.Imaging.BitmapSource.RecoverFromDecodeFailure(Exception e)
   at System.Windows.Media.Imaging.BitmapSource.get_DUCECompatiblePtr()
   at System.Windows.Media.Imaging.BitmapSource.UpdateBitmapSourceResource(Channel channel, Boolean skipOnChannelCheck)
   at System.Windows.Media.Imaging.BitmapSource.UpdateResource(Channel channel, Boolean skipOnChannelCheck)
   at System.Windows.Media.Imaging.BitmapSource.AddRefOnChannelCore(Channel channel)
   at System.Windows.Media.Imaging.BitmapSource.System.Windows.Media.Composition.DUCE.IResource.AddRefOnChannel(Channel channel)
   at System.Windows.Media.RenderData.System.Windows.Media.Composition.DUCE.IResource.AddRefOnChannel(Channel channel)
   at System.Windows.UIElement.RenderContent(RenderContext ctx, Boolean isOnChannel)
   at System.Windows.Media.Visual.RenderRecursive(RenderContext ctx)
   at System.Windows.Media.Visual.UpdateChildren(RenderContext ctx, ResourceHandle handle)

[goes on a whole lot of RenderRecursive + UpdateChildren]

Coordinator
Mar 11, 2010 at 9:08 PM

Yeah, I can confirm this too.  It is very strange.  Apparently the design-time experience in VS2010 creates my ColorKeyBitmap and displays it before setting the Source property.  The result is a 0x0 bitmap, which causes WPF to fail internally.

I did discover one workaround:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:utils="clr-namespace:Microsoft.DwayneNeed.Media.Imaging;assembly=Microsoft.DwayneNeed"
        Title="MainWindow" Height="350" Width="525">
  <Window.Resources>
    <Image x:Key="img" Source="silly.bmp"/>
  </Window.Resources>
    <Image>
      <Image.Source>
        <!-- This won't work because the image source is async, and WIC handle is created 1x1 and can never change. -->
        <!--<utils:ColorKeyBitmap TransparentColor="Red" Source="http://upload.wikimedia.org/wikipedia/meta/2/2a/Nohat-logo-nowords-bgwhite-200px.jpg"/>-->

        <!-- This works at run-time, but crashes Cider because Source is null when Cider tries to display it. -->
        <!--<utils:ColorKeyBitmap TransparentColor="Red" Source="silly.bmp"/>-->

        <!-- This works both at runtime and design time, for some reason Cider will set the Source property before displaying the image. -->
        <utils:ColorKeyBitmap TransparentColor="Red" Source="{Binding Source={StaticResource img}, Path=Source}"/>
      </Image.Source>
    </Image>
</Window>

Good luck!