Image that is grayed when disabled, for use in buttons, etc.





5.00/5 (2 votes)
AutoGrayImage: An image class that changes to grayscale when it becomes disabled.
Download GrayImage.zip - 61.83 KB
Introduction
A well known WPF misfeature is that images of disabled (toolbar or other) buttons, or menuitems, are not displayed in grayscale. There are three well known ways around:- Set the image's
Opacity
with a trigger. - Set the image's
Effect
. - Use a custom image class.
Using the code
<Button> <my:AutoGrayImage Source2="/GrayImage;component/Images/Tulips.png" /> </Button>In the XAML, just replace your
Image
with AutoGrayImage
, and set Source2
instead of the Source
property. Here is how the result looks:
The Code
You should also add the following class to your project:
public class AutoGrayImage : Image
{
public AutoGrayImage()
{
IsEnabledChanged += new
DependencyPropertyChangedEventHandler(AutoGrayImage_IsEnabledChanged);
}
void AutoGrayImage_IsEnabledChanged(object sender,
DependencyPropertyChangedEventArgs e)
{
Source = IsEnabled?Source2:GrayedImage;
}
FormatConvertedBitmap GrayedImage = null;
public static readonly DependencyProperty Source2Property =
DependencyProperty.Register("Source2", typeof(BitmapSource),
typeof(AutoGrayImage), new PropertyMetadata(null,
OnSource2Changed));
/// <summary>
/// Sets the image to be grayed, or not.
/// </summary>
public BitmapSource Source2
{
get { return (BitmapSource)GetValue(Source2Property); }
set { SetValue(Source2Property, value); }
}
static void OnSource2Changed(DependencyObject sender,
DependencyPropertyChangedEventArgs e)
{
AutoGrayImage s = sender as AutoGrayImage;
if (s.Source2 == null)
{
s.GrayedImage = null;
}
else
{
s.GrayedImage = new FormatConvertedBitmap(s.Source2,
PixelFormats.Gray8, null, 0);
s.OpacityMask = new ImageBrush(s.Source2);
}
s.AutoGrayImage_IsEnabledChanged(s, new
DependencyPropertyChangedEventArgs());
}
}
I admit that introducing another Source
property, i.e., Source2
, is not entirely clean. However, it seemed to be the option with the best (cleanliness / lines of code written) ratio.