2009-06-06 4 views
3

Мне нужно изображение, которое отключено при отключении (IsEnabled = False). Выделенная версия изображения может быть выполнена путем чтения BitmapImage в формате FormatConvertedBitmap, который показан here.Как я могу сделать изображение 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

возможно дубликат [Есть ли способ, чтобы обесцветить изображения на кнопку Thats отключенной?] (Http://stackoverflow.com/questions/4304972/is-there-a-way-to-desaturate- a-image-on-a-button-thats-disabled) – Justin

ответ

9

Посмотрите this link

EDIT: Или this one (все, что вам нужно, это класс AutoGreyableImage)

+0

Спасибо! Но я не готов покупать весь пакет Infragistics Win Client только для этого класса :) – Oskar

+0

Извините, я не понял, что это был элемент управления Infragistics ... У меня есть еще одна ссылка, я обновлю свой ответ –

+0

Еще раз спасибо , решение в новой ссылке отлично работает! – Oskar

0

Создать класс DisableableImage, который является типичный элемент управления WPF. Внутри разместите два элемента: изображение и прямоугольник, который появляется только тогда, когда элемент управления отключен. Прямоугольник должен иметь ту же ширину и высоту, что и изображение, и должен накладывать изображение. Если цвет серого и альфа около 40%, вы должны получить эффект, похожий на фактическое сечение изображения - без всяких усилий, чтобы фактически изменить изображение.

+0

Это хорошая идея, но если вы попробуете ее, она не будет похожа на эффект, который пытается достичь квестонер. Он выглядит как полупрозрачный серый прямоугольник над изображением. :) –

+0

Я предполагаю, что это зависит от того, что кто-то означает «серым», но да, остался бы немного цвета. –

+0

Мало того, что цвет будет оставлен - контур будет изменен с содержимого значка на прямоугольник. Это совсем другое. Вы могли бы просто полностью скрыть значок. – ygoe

2

Если вы используете это много, подумайте о создании пользовательского эффекта, представленного с .NET 3.5 SP1 (not bitmapeffect), чтобы сделать такую ​​операцию на вашем графическом процессоре. этот эффект затем можно легко контролировать с помощью триггеров.

5

Я сделал небольшое сравнение на основе следующих решений.

Так как я уже имел лицензионную для Infragistics Net Advantage для WPF это было легко, чтобы попробовать его

Вот результат

enter image description here

Так что лучший подход зависит от результатов вы после. Что касается меня, то я думаю, что результат, созданный из Infragistics, слишком яркий, AutoGreyableImage делает довольно хорошую работу (Идентичный результат для подхода 1 (ссылка OP)) и GreyscaleEffect дает лучший результат.

2

Более полная версия AutoGreyableImage от Thomas Lebrun. Для всех, кого это интересует, я начал использовать класс Томаса Лебрунса и столкнулся с несколькими исключениями из-за нулевой ссылки, а также узнал, что изображение не будет отключено, если свойство 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' 
      } 

     } 

    } 
} 
Смежные вопросы