WPF Sample Series – Solution for the Obsolete BitmapEffect Property and Rendering an OuterGlowBitmapEffect

Since the release of .NET 3.5 SP1, I have been getting a new Visual Studio warning in my code where I have assigned a BitmapEffect to a UIElement.  Specifically I was using the OuterGlowBitmapEffect.

Warning 1 ‘Public Property BitmapEffect() As System.Windows.Media.Effects.BitmapEffect’ is obsolete: ‘Avoid using BitmapEffects as they have very poor performance characteristics.  They will be deprecated in a future version.  Consider using the UIElement.Effect property and ShaderEffects where appropriate instead.’

Problem

I needed an outer glow effect in my application so I read up on the new Effects property and the new Effect and ShaderEffects classes.  However, I could not find a replacement for the OuterGlowBitmapEffect that would work with the new UIElement.Effects property.

UIElement.BitmapEffect property is obsolete, making those bitmap effects we have been using obsolete also.

On the surface it seems the new UIElement.Effect property does not have an OuterGlowEffect class we can use to replace the OuterGlowBitmapEffect we have been using.

Solution

Today I was reading a WPF thread and found the solution that I want to share with you.

Outerglow

The simple example has four buttons, two with effects declared in  XAML the other two effects assigned in code.  When using the obsolete BitmapEffect property in XAML, no warnings are given by Visual Studio.  The warnings are only provided when you assign the BitmapEffect property a value in code.

Most of you are familar with the OutGlowBitmapEffect.  There is no new class deriving from Effect or ShaderEffect that has a name with OuterGlow in it.

The solution is to use the new DropShadowEffect and set its ShadowDepth to zero.  Presto, we not have an outer glow effect we need.  You can also play around with the BlurRadius property to get the glow size you want.

Here is the best part of all, your outer glow will now be hardware rendered and not software rendered, giving you a nice performance boost. 

You can read about the hardware performance boost in this post GPU-Accelerated Custom Effects for WPF.

<Window x:Class="Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
  
  <StackPanel>
    
    <Button Margin="11" Content="OuterGlowBitmpEffect - XAML">
      <Button.BitmapEffect>
        <OuterGlowBitmapEffect GlowColor="Blue" GlowSize="5" />
      </Button.BitmapEffect>
    </Button>

    <Button Margin="11" Content="DropShadowEffect - XAML">
      <Button.Effect>
        <DropShadowEffect ShadowDepth="0" Color="Blue" BlurRadius="10" />
      </Button.Effect>
    </Button>

    <Button Margin="11" Content="OuterGlowBitmpEffect - Code" x:Name="btnOuterGlow" />

    <Button Margin="11" Content="DropShadowEffect - Code" x:Name="btnDropShadow" />

  </StackPanel>
  
</Window>

The below line of code, Me.btnOuterGlow.BitmapEffect = objOutGlow gets flagged by Visual Studio with the warning message in the below comment.

Below the comment is the code for assigning the new DropShadowEffect to the button in code.  By setting the ShadowDepth to zero and increasing the BlurRadius to ten, you get the same outer glow effect you had with the now obsolete OuterGlowBitmapEffect .

Imports System.Windows.Media.Effects

Class Window1

    Private Sub Window1_Loaded(ByVal sender As Object, _
            ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded

        Dim objOuterGlow As New OuterGlowBitmapEffect
        objOuterGlow.GlowSize = 5
        objOuterGlow.GlowColor = Colors.Red
        Me.btnOuterGlow.BitmapEffect = objOuterGlow

        'Public Property BitmapEffect() As System.Windows.Media.Effects.BitmapEffect
        ' is obsolete.  Avoid using BitmapEffects as they have very poor performance 
        'characteristics.  They will be deprecated in a future version.  

        'Consider using the UIElement.Effect property and ShaderEffects where appropriate 
        'instead.

        Dim objDropShadow As New DropShadowEffect
        objDropShadow.ShadowDepth = 0
        objDropShadow.BlurRadius = 10
        objDropShadow.Color = Colors.Red
        Me.btnDropShadow.Effect = objDropShadow

    End Sub
End Class

Download

After downloading the below package, you must rename it from .doc to .zip.  This is a requirement of WordPress.com

Download Source (17 KB)

Close

Have a great day,

Just a grain of sand on the worlds beaches.

7 Responses to WPF Sample Series – Solution for the Obsolete BitmapEffect Property and Rendering an OuterGlowBitmapEffect

  1. xr280xr says:

    Thanks! That’s awesome! I’m finding the effect automatically gets inherited by all child controls though. Is there a way to stop this? I tried setting Effect=”{x:Null}” on a child control but it didn’t work.

    • One way to accomplish this is to cheat. LOL.

      Grid
      Border
      all your content goes here

      Border
      add you effects here

      /Grid

      Since the Grid will stack them you are in effect having two layers. One has the effect the other does not. You can play around with which one is on top and adjust the various properties to get the results you need.

      Cheers,

      Karl

  2. [...] WPF Sample Series – Solution for the Obsolete BitmapEffect Property and Rendering an OuterGlowBitm… [...]

  3. [...] WPF Sample Series – Solution for the Obsolete BitmapEffect Property and Rendering an OuterGlowBitm…   No [...]

  4. weitzhandler says:

    Hi Karl and thank you for this post, it was very helpful to me.
    I had a custom button control and I used to use the OuterGlowBitmapEffect. now it got messed up as they took the OuterGlow out of action.

    I am trying to achieve the following with the DropShadowEffect but I am unable:
    1) When target-element.IsMouseOver: the DropShadow’s color should be set to {TemplateBinding MouseOverEffectColor}, and the BlurRadius to 5.
    2) When the button IsDefaulted, it should set the color to the ImageButton’s DefaultedEffectColor, plus it should animate the effect to move from 0 to 5 auto-reverse forever.

    How can this be done?

Follow

Get every new post delivered to your Inbox.

Join 167 other followers