Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grey out image on button when element is disabled (simple and beautiful way)

Tags:

I want to grey out my images (on the buttons) when the buttons are disabled. When I have text (no images) on the button, the text is greyed out (With Images as Button Content they are not grey out). Is there any simple and beautiful way to do that?

This is my xaml file:

<Window x:Class="WpfApplication2.MainWindow"         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         Title="MainWindow" Height="350" Width="525">     <Grid>         <Grid.RowDefinitions>                 <RowDefinition Height="Auto" />                 <RowDefinition Height="*"/>         </Grid.RowDefinitions>         <ToolBarTray VerticalAlignment="Top" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" IsLocked="true" Grid.Row="0">             <ToolBar Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Band="1" BandIndex="1">                 <Button Command="{Binding Button1}" RenderOptions.BitmapScalingMode="NearestNeighbor">                     <Button.Content>                         <Image Source="open.ico"></Image>                     </Button.Content>                 </Button>                 <Button Command="{Binding Button2}" RenderOptions.BitmapScalingMode="NearestNeighbor">                     <Button.Content>                         <Image Source="open.ico"></Image>                     </Button.Content>                 </Button>             </ToolBar>         </ToolBarTray>     </Grid> </Window> 

and this is my code behind file:

public partial class MainWindow : Window {     private RelayCommand _button1;     private RelayCommand _button2;      public MainWindow()     {         InitializeComponent();         DataContext = this;     }      public ICommand Button1     {         get         {             if (_button1 == null)             {                 _button1 = new RelayCommand(Button1E, Button1C);             }             return _button1;         }     }      public ICommand Button2     {         get         {             if (_button2 == null)             {                 _button2 = new RelayCommand(Button2E, Button2C);             }             return _button2;         }     }      public void Button1E(object parameter)     {         Trace.WriteLine("Button 1");     }      public bool Button1C(object parameter)     {         return true;     }      public void Button2E(object parameter)     {         Trace.WriteLine("Button 2");     }      public bool Button2C(object parameter)     {         return false;     } } 
like image 500
David Avatar asked Jul 03 '12 06:07

David


People also ask

How do I GREY out disabled button?

You should put your CSS styles into a stylesheet rather than directly onto the HTML . Once it's set as a CSS style rule you can then use the :disabled flag to set styles for when that attribute is true. You can not use the :disabled flag on inline styles.

Is it ok to grey out disabled buttons?

Going from gray to fully colored is an unpredictable change that can affect user expectations. For a smooth and seamless experience, it's best to avoid graying out your disabled buttons. Instead, you should decrease the opacity to make it transparent.


2 Answers

As Thomas Lebrun says in his post How to gray the icon of a MenuItem ? the best way at the moment is probably to create a little class, AutoGreyableImage, which allow you to have an image that will be turn in gray automatically when the control is deactivated.

Here is how you can use it:

<MenuItem Header="Edit">     <MenuItem x:Name="miPaste"               Header="Paste">         <MenuItem.Icon>             <local:AutoGreyableImage Source="pack://application:,,,/Images/Paste.png"                                                    />         </MenuItem.Icon>     </MenuItem> </MenuItem>   

And here is the implementation:

/// <summary> /// Class used to have an image that is able to be gray when the control is not enabled. /// Author: 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 property.         IsEnabledProperty.OverrideMetadata(typeof(AutoGreyableImage), new FrameworkPropertyMetadata(true, new PropertyChangedCallback(OnAutoGreyScaleImageIsEnabledPropertyChanged)));     }     /// <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>     private static void OnAutoGreyScaleImageIsEnabledPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs args)     {         var autoGreyScaleImg = source as AutoGreyableImage;         var isEnable = Convert.ToBoolean(args.NewValue);         if (autoGreyScaleImg != null)         {             if (!isEnable)             {                 // Get the source bitmap                 var bitmapImage = new BitmapImage(new Uri(autoGreyScaleImg.Source.ToString()));                 // Convert it to Gray                 autoGreyScaleImg.Source = new FormatConvertedBitmap(bitmapImage, PixelFormats.Gray32Float, null, 0);                 // Create Opacity Mask for greyscale image as FormatConvertedBitmap does not keep transparency info                 autoGreyScaleImg.OpacityMask = new ImageBrush(bitmapImage);             }             else             {                 // Set the Source property to the original value.                 autoGreyScaleImg.Source = ((FormatConvertedBitmap) autoGreyScaleImg.Source).Source;                 // Reset the Opcity Mask                 autoGreyScaleImg.OpacityMask = null;             }         }     } }   

Here is the result:

Result of applying class to perform grayscale rendering when disabled

Sources

like image 146
David Avatar answered Oct 23 '22 13:10

David


You could use a pixel shader to do this automatically.

like image 43
Kent Boogaart Avatar answered Oct 23 '22 12:10

Kent Boogaart