我要灰我的图片(上的按钮),当按钮被禁用。 当我对按钮文本(无图像),文本是灰色的(带图像的按钮内容他们不变灰)。 有没有什么简单而美丽的方式来做到这一点?
这是我的XAML文件:
<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>
这是我的隐藏文件的代码:
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;
}
}
Answer 1:
正如托马斯·勒布伦在他的帖子中写道: 如何灰色菜单项的图标? 目前最好的办法可能是创建一个小的类,AutoGreyableImage,这让你有将在灰色自动当控制被停用轮到的图像。
这里是你如何使用它:
<MenuItem Header="Edit">
<MenuItem x:Name="miPaste"
Header="Paste">
<MenuItem.Icon>
<local:AutoGreyableImage Source="pack://application:,,,/Images/Paste.png"
/>
</MenuItem.Icon>
</MenuItem>
</MenuItem>
这里是实现:
/// <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;
}
}
}
}
下面是结果:
来源
Answer 2:
Answer 3:
由AutoGreyableImage更完整的版本托马斯·勒布伦 。 任何有兴趣,我开始使用托马斯Lebruns类,跑进一对夫妇nullreference异常,以及找出如果IsEnabled属性设置第一和源之后设置图像也不会被禁用。
因此,这里的终于奏效了,我的类。 Àpropos,你当然可以增加不透明度的事情到这一点,但我决定离开,截至图像周围的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'
}
}
}
}
Answer 4:
或附加属性相同。
<Image behaviors:GrayoutImageBehavior.GrayOutOnDisabled="True" Source="/WpfApp;component/Resources/picture.png" />
GrayoutImageBehavior:
public class GrayoutImageBehavior
{
public static readonly DependencyProperty GrayOutOnDisabledProperty = DependencyProperty.RegisterAttached("GrayOutOnDisabled", typeof(bool), typeof(GrayoutImageBehavior), new PropertyMetadata(default(bool), OnGrayOutOnDisabledChanged));
public static void SetGrayOutOnDisabled(Image element, bool value) { element.SetValue(GrayOutOnDisabledProperty, value); }
public static bool GetGrayOutOnDisabled(Image element) { return (bool)element.GetValue(GrayOutOnDisabledProperty); }
private static void OnGrayOutOnDisabledChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
Image image = (Image) obj;
image.IsEnabledChanged -= OnImageIsEnabledChanged;
if ((bool)args.NewValue)
image.IsEnabledChanged += OnImageIsEnabledChanged;
ToggleGrayOut(image); // initial call
}
private static void OnImageIsEnabledChanged(object sender, DependencyPropertyChangedEventArgs args)
{
var image = (Image)sender;
ToggleGrayOut(image);
}
private static void ToggleGrayOut(Image image)
{
try
{
if (image.IsEnabled)
{
var grayImage = image.Source as FormatConvertedBitmap;
if (grayImage != null)
{
image.Source = grayImage.Source; // Set the Source property to the original value.
image.OpacityMask = null; // Reset the Opacity Mask
image.Opacity = 1.0;
}
}
else
{
var bitmapImage = default(BitmapImage);
if (image.Source is BitmapImage)
bitmapImage = (BitmapImage) image.Source;
else if (image.Source is BitmapSource) // assume uri source
bitmapImage = new BitmapImage(new Uri(image.Source.ToString()));
if (bitmapImage != null)
{
image.Source = new FormatConvertedBitmap(bitmapImage, PixelFormats.Gray32Float, null, 0); // Get the source bitmap
image.OpacityMask = new ImageBrush(bitmapImage); // Create Opacity Mask for grayscale image as FormatConvertedBitmap does not keep transparency info
image.Opacity = 0.3; // optional: lower opacity
}
}
}
catch (Exception ex)
{
LogicLogger.WriteLogEntry("Converting image to grayscale failed", LogLevel.Debug, false, ex);
}
}
}
Answer 5:
我已经改变了GrayoutImageBehavior,这样就不会有灰色图像的内存泄漏,导致当用户改变图像“启用”从真实属性设置为false,反之亦然几次。 我已经添加的DependencyProperty举行的灰度图像和灰度图像的不透明蒙板。
public class GrayoutImageBehavior
{
public static readonly DependencyProperty GrayOutOnDisabledProperty = DependencyProperty.RegisterAttached("GrayOutOnDisabled", typeof(bool), typeof(GrayoutImageBehavior), new PropertyMetadata(default(bool), OnGrayOutOnDisabledChanged));
public static void SetGrayOutOnDisabled(Image element, bool value) { element.SetValue(GrayOutOnDisabledProperty, value); }
public static bool GetGrayOutOnDisabled(Image element) { return (bool)element.GetValue(GrayOutOnDisabledProperty); }
private static DependencyProperty GrayImageProperty = DependencyProperty.RegisterAttached("GrayImage", typeof(FormatConvertedBitmap), typeof(GrayoutImageBehavior));
private static void SetGrayImage(Image element, FormatConvertedBitmap value) { element.SetValue(GrayImageProperty, value); }
private static FormatConvertedBitmap GetGrayImage(Image element) { return (FormatConvertedBitmap)element.GetValue(GrayImageProperty); }
private static DependencyProperty GrayImageOpacityMaskProperty = DependencyProperty.RegisterAttached("GrayImageOpacityMask", typeof(Brush), typeof(GrayoutImageBehavior));
private static void SetGrayImageOpacityMask(Image element, Brush value) { element.SetValue(GrayImageOpacityMaskProperty, value); }
private static Brush GetGrayImageOpacityMask(Image element) { return (Brush)element.GetValue(GrayImageOpacityMaskProperty); }
private static void OnGrayOutOnDisabledChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
Image image = (Image)obj;
image.IsEnabledChanged -= OnImageIsEnabledChanged;
if ((bool)args.NewValue)
image.IsEnabledChanged += OnImageIsEnabledChanged;
ToggleGrayOut(image); // initial call
}
private static void OnImageIsEnabledChanged(object sender, DependencyPropertyChangedEventArgs args)
{
var image = (Image)sender;
ToggleGrayOut(image);
}
private static void ToggleGrayOut(Image image)
{
try
{
if (image.IsEnabled)
{
var grayImage = image.Source as FormatConvertedBitmap;
if (grayImage != null)
{
image.Source = grayImage.Source; // Set the Source property to the original value.
image.OpacityMask = null; // Reset the Opacity Mask
//image.Opacity = 1.0;
}
}
else
{
FormatConvertedBitmap grayImage = GetGrayImage(image);
Brush grayOpacityMask = GetGrayImageOpacityMask(image);
if(grayImage == null)
{
var bitmapImage = default(BitmapImage);
if (image.Source is BitmapImage)
bitmapImage = (BitmapImage)image.Source;
else if (image.Source is BitmapSource) // assume uri source
bitmapImage = new BitmapImage(new Uri(image.Source.ToString()));
if (bitmapImage != null)
{
grayImage = new FormatConvertedBitmap(bitmapImage, PixelFormats.Gray32Float, null, 0); // Get the source bitmap
SetGrayImage(image, grayImage);
grayOpacityMask = new ImageBrush(bitmapImage); // Create Opacity Mask for grayscale image as FormatConvertedBitmap does not keep transparency info
SetGrayImageOpacityMask(image, grayOpacityMask);
//image.Opacity = 0.3; // optional: lower opacity
}
}
image.Source = grayImage;
image.OpacityMask = grayOpacityMask;
}
}
catch (Exception ex)
{
//LogicLogger.WriteLogEntry("Converting image to grayscale failed", LogLevel.Debug, false, ex);
}
}
}
文章来源: Grey out image on button when element is disabled (simple and beautiful way)