2009-06-06 32 views
3

我需要禁用时显示为灰色的图像(IsEnabled = False)。通过将BitmapImage读取到显示为here的FormatConvertedBitmap,可以生成图像的灰色版本。如何使WPF图像无法使用?

我已经能够得到这个UserControl的工作,但现在我想在一个专门的图像类相同的行为更灵活。我不关心这是在XAML,代码隐藏还是两者都实现的,但它需要是Image的子类。

的使用可能是:

<DisableableImage Source="Images/image1.png" /> 
<DisableableImage Source="Images/image1.png" IsEnabled="False" /> 

<!-- Since IsEnabled is inherited down the tree, 
    the image will be grayed out like the rest of the button --> 
<Button IsEnabled="False"> 
    <StackPanel Orientation="Horizontal"> 
     <TextBlock>OK</TextBlock> 
     <DisableableImage Source="Images/ok.png" /> 
    </StackPanel> 
</Button> 
+0

可能重复http://stackoverflow.com/questions/4304972/is-there-a-way-to-desaturate- an-image-on-a-button-thats-disabled) – Justin 2014-04-29 18:26:47

回答

9

看一看this link

编辑: 或者this one(所有你需要的是AutoGreyableImage类)

+0

谢谢!但是我没有准备好为这个班级购买整个Infragistics Win Client软件包:) – Oskar 2009-06-06 14:11:42

+0

对不起,我没有意识到这是一个Infragistics控件...我有另一个链接,我会更新我的答案 – 2009-06-06 14:49:27

0

创建DisableableImage类,它是一个典型的WPF控制。在里面放置两个元素:图像和一个矩形,只有当控件被禁用时才会出现。矩形应该与图像的宽度和高度相同,并且应该覆盖图像。使用灰色和约40%的阿尔法颜色,您应该获得类似于实际淡化图像的效果 - 而无需实际修改图像本身。

2

如果您使用此功能,请考虑创建.NET 3.5 SP1(而非bitmapeffect)引入的自定义效果,以在GPU上渲染此类操作。这个效果可以很容易地被触发器控制。

5

我根据以下解决方案做了一些比较。通过托马斯Levesque的

  • Greyscale Effect
  • 提供由OP提供

    • 中链接的方法
    • 的联系

      由于我已经为Infragistics的网络优势授予许可的WPF很容易尝试一下

      下面是结果

      enter image description here

      所以最好的方法取决于什么结果你在之后。至于我,我认为Infragistics的AutoDisabledImage产生的结果太亮,AutoGreyableImage做得不错(与方法1(OP链接)相同的结果)GreyscaleEffect产生最好的结果。

    2

    AutoGreyableImage的更完整版本,作者Thomas Lebrun。对于任何感兴趣的人,我开始使用Thomas Lebruns类,并遇到了几个null引用异常,并发现如果isEnabled属性设置为第一个,而源设置为之后则不会禁用图像。

    所以这里是最终为我做的伎俩的类。关于这一点,你当然可以将不透明的问题添加进去,但我决定把它留给图像周围的xaml。

    using System; 
    using System.Windows; 
    using System.Windows.Controls; 
    using System.Windows.Media.Imaging; 
    using System.Windows.Media; 
    
    namespace MyDisabledImages 
    { 
        /// <summary> 
        /// 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) 
        /// </summary> 
        public class AutoGreyableImage : Image 
        { 
         /// <summary> 
         /// Initializes a new instance of the <see cref="AutoGreyableImage"/> class. 
         /// </summary> 
         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; 
         } 
    
         /// <summary> 
         /// Called when [auto grey scale image source property changed]. 
         /// </summary> 
         /// <param name="source">The source.</param> 
         /// <param name="args">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> 
         protected static void OnAutoGreyScaleImageSourcePropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs ars) 
         { 
          AutoGreyableImage image = GetImageWithSource(source); 
          if (image != null) 
           ApplyGreyScaleImage(image, image.IsEnabled); 
         } 
    
         /// <summary> 
         /// Called when [auto grey scale image is enabled property changed]. 
         /// </summary> 
         /// <param name="source">The source.</param> 
         /// <param name="args">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> 
         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' 
          } 
    
         } 
    
        } 
    } 
    
    的[有没有办法去色上禁用的按钮,多数民众赞成的图像?](