我在我的应用程序的主仪表板中使用Picturebox控件作为Button。当然,PictureBox有一个图片来标识Button的功能。
如果我使用普通的Button控件,当被禁用时,Button的图像会自动变灰。而使用PictureBox就不会出现这种情况。
我怎样才能产生同样的效果呢?效果 使用Picturebox。
选项1:自定义控件(PictureBox)+ColorMatrix。
因为你不想使用按钮,因为当控件被禁用时,你的图像会变成灰色,你可以使用一个 颜色矩阵 改变 PictureBox.BackgroundImage
或(Image)转换为灰度。
您在这里看到的 GrayScale 矩阵使用众所周知的值将 Image 转换为按比例的灰度颜色表示。您可以找到对同一矩阵对象的其他解释,可能会产生不同的结果。测试一些或自己调整它可能会很有趣。
GrayScale过程是以 扩展方法因为它可能在其他情况下派上用场。它扩展了Image类,增加了一个 ToGrayScale()
方法(当然您也可以扩展Bitmap类:您只需要调用Image扩展,将Bitmap转换为Image,或者根据您的喜好调用其他方式)。
假设你有一个自定义控件,当BackgroundImage被改变时,你可以创建一个GrayScale表示并存储它。
然后覆盖 OnEnabledChanged
来改变BackgroundImage为原始或其GrayScale版本。一个简单的检查可以防止代码在内部改变BackgroundImage时生成一个新的GrayScale图像(这是一个有点简化的方法,你应该画背景来代替。我会在有能力的时候更新它)。)
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
[DesignerCategory("Code")]
public class ButtonPicture : PictureBox
{
private Image m_sourceImage = null;
private Image m_grayImage = null;
public ButtonPicture() { }
protected override void OnEnabledChanged(EventArgs e) {
base.OnEnabledChanged(e);
this.BackgroundImage = this.Enabled ? m_sourceImage : m_grayImage;
}
protected override void OnBackgroundImageChanged(EventArgs e) {
base.OnBackgroundImageChanged(e);
if (this.BackgroundImage == m_sourceImage ||
this.BackgroundImage == m_grayImage) return;
m_sourceImage = this.BackgroundImage;
m_grayImage = m_sourceImage.ToGrayScale();
}
protected override void Dispose(bool disposing) {
if (disposing) {
m_grayImage.Dispose();
}
base.Dispose(disposing);
}
}
的扩展方法。
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
public static class ImageExtensions
{
static ColorMatrix grayMatrix = new ColorMatrix(new float[][]
{
new float[] { .2126f, .2126f, .2126f, 0, 0 },
new float[] { .7152f, .7152f, .7152f, 0, 0 },
new float[] { .0722f, .0722f, .0722f, 0, 0 },
new float[] { 0, 0, 0, 1, 0 },
new float[] { 0, 0, 0, 0, 1 }
});
public static Bitmap ToGrayScale(this Image source) {
var grayImage = new Bitmap(source.Width, source.Height, source.PixelFormat);
grayImage.SetResolution(source.HorizontalResolution, source.VerticalResolution);
using (var g = Graphics.FromImage(grayImage))
using (var attributes = new ImageAttributes()) {
attributes.SetColorMatrix(grayMatrix);
g.DrawImage(source, new Rectangle(0, 0, source.Width, source.Height),
0, 0, source.Width, source.Height, GraphicsUnit.Pixel, attributes);
return grayImage;
}
}
}
方案二:ControlPaint + PictureBox.Paint事件。 蹇
您可以使用 ControlPaint.DrawImageDisabled() 画法 残疾 位图。
PictureBox.Paint
事件,并通过 e.Graphics
方法的对象。Image
参数可以是 PictureBox.Image
属性值。►对比左边的图片。残疾 使用ColorMatrix,右边是Image。残疾 使用ControlPaint方法。
private void buttonPicture_Paint(object sender, PaintEventArgs e)
{
var pict = sender as PictureBox;
if (pict != null && (!pict.Enabled)) {
using (var img = new Bitmap(pict.Image, pict.ClientSize)) {
ControlPaint.DrawImageDisabled(e.Graphics, img, 0, 0, pict.BackColor);
}
}
}