How can I make a WPF Image disableable?

前端 未结 5 1193
野趣味
野趣味 2021-01-21 04:54

I need an Image that is grayed out when disabled (IsEnabled=False). A grayed out version of the image can be produced by reading the BitmapImage into a FormatConvertedBitmap whi

5条回答
  •  花落未央
    2021-01-21 05:10

    More complete version of the AutoGreyableImage by Thomas Lebrun. For anyone interested, I started using Thomas Lebruns class and ran into a couple of nullreference exceptions, as well as finding out that an image would not be disabled if the isEnabled property was set first and the source set after.

    So here's the class that finally did the trick for me. À propos, you can of course add the matter of opacity into this, but I decided to leave that up to the xaml around the image.

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media.Imaging;
    using System.Windows.Media;
    
    namespace MyDisabledImages
    {
        /// 
        /// Class used to have an image that is able to be gray when the control is not enabled.
        /// Based on the version by Thomas LEBRUN (http://blogs.developpeur.org/tom)
        /// 
        public class AutoGreyableImage : Image
        {
            /// 
            /// Initializes a new instance of the  class.
            /// 
            static AutoGreyableImage()
            {
                // Override the metadata of the IsEnabled and Source property.
                IsEnabledProperty.OverrideMetadata(typeof(AutoGreyableImage), new FrameworkPropertyMetadata(true, new PropertyChangedCallback(OnAutoGreyScaleImageIsEnabledPropertyChanged)));
                SourceProperty.OverrideMetadata(typeof(AutoGreyableImage), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnAutoGreyScaleImageSourcePropertyChanged)));
            }
    
            protected static AutoGreyableImage GetImageWithSource(DependencyObject source)
            {
                var image = source as AutoGreyableImage;
                if (image == null)
                    return null;
    
                if (image.Source == null)
                    return null;
    
                return image;
            }
    
            /// 
            /// Called when [auto grey scale image source property changed].
            /// 
            /// The source.
            /// The  instance containing the event data.
            protected static void OnAutoGreyScaleImageSourcePropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs ars)
            {
                AutoGreyableImage image = GetImageWithSource(source);
                if (image != null)
                    ApplyGreyScaleImage(image, image.IsEnabled);
            }
    
            /// 
            /// Called when [auto grey scale image is enabled property changed].
            /// 
            /// The source.
            /// The  instance containing the event data.
            protected static void OnAutoGreyScaleImageIsEnabledPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs args)
            {
                AutoGreyableImage image = GetImageWithSource(source);
                if (image != null)
                {
                    var isEnabled = Convert.ToBoolean(args.NewValue);
                    ApplyGreyScaleImage(image, isEnabled);
                }
            }
    
            protected static void ApplyGreyScaleImage(AutoGreyableImage autoGreyScaleImg, Boolean isEnabled)
            {
                try
                {
                    if (!isEnabled)
                    {
                        BitmapSource bitmapImage = null;
    
                        if (autoGreyScaleImg.Source is FormatConvertedBitmap)
                        {
                            // Already grey !
                            return;
                        }
                        else if (autoGreyScaleImg.Source is BitmapSource)
                        {
                            bitmapImage = (BitmapSource)autoGreyScaleImg.Source;
                        }
                        else // trying string 
                        {
                            bitmapImage = new BitmapImage(new Uri(autoGreyScaleImg.Source.ToString()));
                        }
                        FormatConvertedBitmap conv = new FormatConvertedBitmap(bitmapImage, PixelFormats.Gray32Float, null, 0);
                        autoGreyScaleImg.Source = conv;
    
                        // Create Opacity Mask for greyscale image as FormatConvertedBitmap does not keep transparency info
                        autoGreyScaleImg.OpacityMask = new ImageBrush(((FormatConvertedBitmap)autoGreyScaleImg.Source).Source); //equivalent to new ImageBrush(bitmapImage)
                    }
                    else
                    {
                        if (autoGreyScaleImg.Source is FormatConvertedBitmap)
                        {
                            autoGreyScaleImg.Source = ((FormatConvertedBitmap)autoGreyScaleImg.Source).Source;
                        }
                        else if (autoGreyScaleImg.Source is BitmapSource)
                        {
                            // Should be full color already.
                            return;
                        }
    
                        // Reset the Opcity Mask
                        autoGreyScaleImg.OpacityMask = null;
                    }
                }
                catch (Exception)
                {
                    // nothin'
                }
    
            }
    
        }
    }
    

提交回复
热议问题