2009-06-06 13 views
3

Ich brauche ein Bild, das ausgegraut ist, wenn es deaktiviert ist (IsEnabled = False). Eine ausgegraute Version des Bildes kann erzeugt werden, indem das BitmapImage in eine FormatConvertedBitmap gelesen wird, die here angezeigt wird.Wie kann ich ein WPF-Image deaktivieren?

Ich konnte dies mit einem UserControl arbeiten, aber jetzt Ich möchte das gleiche Verhalten in einer speziellen Bildklasse für mehr Flexibilität. Es ist mir egal, ob dies in XAML, Code-Behind oder beiden implementiert ist, aber es muss eine Unterklasse von Image sein. sein

könnte die Nutzung:

<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

möglich Duplikat [Gibt es einen Weg, um ein Bild auf einem Knopf, das ist deaktiviert entsättigen?] (Http://stackoverflow.com/questions/4304972/is-there-a-way-to-desaturate- An-Bild-auf-Knopf-Thats-deaktiviert) – Justin

Antwort

9

bei Werfen Sie einen Blick this link

EDIT: Oder this one (alles, was Sie brauchen, ist die AutoGreyableImage Klasse)

+0

Danke! Aber ich bin nicht bereit, das ganze Infragistics Win Client-Paket nur für diese Klasse zu kaufen :) – Oskar

+0

Entschuldigung, ich wusste nicht, dass es eine Infragistics Kontrolle war ... Ich habe einen anderen Link, ich werde meine Antwort aktualisieren –

+0

Nochmals vielen Dank , die Lösung in der neuen Verbindung funktioniert super! – Oskar

0

eine DisableableImage Klasse erstellen, die eine ist typische WPF-Kontrolle. Platzieren Sie im Inneren zwei Elemente: das Bild und ein Rechteck, das nur angezeigt wird, wenn das Steuerelement deaktiviert ist. Das Rechteck sollte die gleiche Breite und Höhe wie das Bild haben und das Bild überlagern. Mit einer Farbe von Grau und einem Alpha von etwa 40% sollten Sie einen Effekt erzielen, der dem Ausgrauen des Bildes ähnlich ist - ohne den Aufwand, das Bild selbst zu verändern.

+0

Es ist eine nette Idee, aber wenn du es versuchst, sieht es nicht so aus wie der Effekt, den der Questoner zu erreichen versucht. Es sieht einfach wie ein halbtransparentes graues Rechteck über einem Bild aus. :) –

+0

Ich denke, das hängt davon ab, was genau jemand mit "ausgegraut" meint, aber ja, da wäre noch etwas Farbe übrig. –

+0

Nicht nur, dass noch Farbe übrig wäre - der Umriss würde vom Icon-Inhalt in ein Rechteck geändert werden. Das ist etwas ganz anderes. Sie können auch das Symbol vollständig ausblenden. – ygoe

2

Wenn Sie dies häufig verwenden, sollten Sie einen benutzerdefinierten Effekt erstellen, der mit .NET 3.5 SP1 (nicht Bitmap-Effekt) eingeführt wurde, um einen solchen Vorgang auf Ihrer GPU darzustellen. Dieser Effekt kann dann leicht durch Trigger gesteuert werden.

5

Ich machte einen kleinen Vergleich basierend auf den folgenden Lösungen.

ausgebrachten Links

Da ich schon ein licens für die Infragistics Net Vorteil für WPF hatte war es einfach, es auszuprobieren

Hier ist das Ergebnis

enter image description here

So ist der beste Ansatz, was hängt Ergebnisse Du bist hinterher. Ich denke, das Ergebnis von AutoDisabledImage von Infragistics ist zu hell, AutoGreyableImage macht einen ziemlich guten Job (Identisches Ergebnis zu Ansatz 1 (OP Link)) und GreyscaleEffect produziert das beste Ergebnis.

2

Komplette Version des AutoGreableImage von Thomas Lebrun. Für alle Interessierten nutzte ich die Thomas Lebruns-Klasse und stieß dabei auf eine Reihe von NULLReference-Ausnahmen sowie darauf, dass ein Bild nicht deaktiviert würde, wenn die isEnabled-Eigenschaft zuerst festgelegt und die Quelle danach festgelegt wurde.

Also hier ist die Klasse, die endlich den Trick für mich gemacht hat. À propos, du kannst natürlich die Frage der Undurchsichtigkeit in dieses Thema einfügen, aber ich habe beschlossen, das dem Xaml um das Bild zu überlassen.

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

     } 

    } 
} 
Verwandte Themen