如何使WPF图像无法使用?

我需要一个在禁用时灰显的图像(IsEnabled = False)。 通过将BitmapImage读入此处显示的FormatConvertedBitmap,可以生成图像的灰色版本。

我已经能够使用UserControl,但现在我想在专门的Image类中使用相同的行为以获得更大的灵活性。 我不在乎这是在XAML,代码隐藏还是两者中实现,但它需要是Image的子类。

用法可能是:

    

看看这个链接

编辑:或者这个 (你需要的只是AutoGreyableImage类)

我根据以下解决方案进行了一些比较。

  • OP提供的链接方法
  • Thomas Levesque提供的链接
    • AutoDisabledImage
    • AutoGreyableImage
  • 灰度效应

由于我已经获得了WPF Infragistics Net Advantage的许可证,因此很容易尝试

这是结果

在此处输入图像描述

所以最好的方法取决于你所追求的结果。 至于我,我认为Infragistics的AutoDisabledImage产生的结果太亮了, AutoGreyableImage做得相当不错(方法1(OP链接)的结果相同)GreyscaleEffect产生最好的结果。

如果您经常使用它,请考虑使用.NET 3.5 SP1(而非bitmapeffect)创建自定义效果,以在GPU上呈现此类操作。 然后可以通过触发器轻松控制此效果。

Thomas Lebrun提供的更完整版AutoGreyableImage。 对于任何感兴趣的人,我开始使用Thomas Lebruns类并遇到几个空引用exception,并且发现如果首先设置了isEnabled属性并且之后设置了源,则不会禁用图像。

所以这是最后为我做的伎俩。 提议,你当然可以在这里加入不透明度的问题,但我决定把它留给图像周围的xaml。

 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' } } } } 

创建一个典型的WPF控件的DisableableImage类。 在里面,放置两个元素:图像和仅在禁用控件时出现的矩形。 矩形应与图像的宽度和高度相同,并应覆盖图像。 使用灰色和大约40%的alpha值时,您应该获得类似于实际灰化图像的效果 – 而无需实际修改图像本身。