BilinearGradientBrushExtension, custom brush in WPF using MarkupExtension instead
来源:互联网 发布:网络受限制或无连接 编辑:程序博客网 时间:2024/04/29 15:41
WPF的类库现在锁死不让继承实现自定义的Brush,因为基类的brush含有抽象而且是internal的一些函数,像internal abstract System.Windows.Media.Composition.DUCE.ResourceHandle AddRefOnChannelCore(System.Windows.Media.Composition.DUCE.Channel channel),就没法继承实现,而且一般的DrawingBrush, ImageBrush都是sealed。而我这次需要一个相当于2维的GradientBrush一样的东西来实现传入一个颜色矩阵,画出一副ColorMap的东西。因为直接从brush继承设置想直接从imagesource继承都不可能,只好用MarkupExtension的方法绕:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Markup;
using System.Windows.Media.Imaging;
using System.Windows.Media;
using System.Windows;
using System.Windows.Media.Animation;
using System.ComponentModel;
[MarkupExtensionReturnType(typeof(Brush))]
class BilinearGradientBrushExtension:MarkupExtension,INotifyPropertyChanged
{
List<Color> colorMatrix = new List<Color>();
int countX, countY;
private void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public List<Color> ColorMatrix
{
get { return colorMatrix; }
set { colorMatrix = value ; OnPropertyChanged("ColorMatrix"); }
}
public int CountY
{
get { return countY; }
set { countY = value; }
}
public int CountX
{
get { return countX; }
set { countX = value; }
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
int i = ColorMatrix.Count;
int[] pixelValues = GeneratePixelValues();
WriteableBitmap bmp = new WriteableBitmap(countX, countY, 96, 96, PixelFormats.Pbgra32, null);
bmp.WritePixels(new Int32Rect(0, 0, countX, countY), pixelValues, pixelValues.Length, 0);
ImageBrush brush = new ImageBrush(bmp);
return brush;
}
private int[] GeneratePixelValues()
{
int pixelCount = countX * countY;
int[] pixelValues = new int[pixelCount];
for (int i = 0; i < countY; i++)
{
for (int j = 0; j < countX; j++)
{
Color c = ColorMatrix[i * countY + j];
byte a = (byte)c.A;
byte r = (byte)c.R;
byte g = (byte)c.G;
byte b = (byte)c.B;
pixelValues[i*countY +j] = (a << 24) + (r << 16) + (g << 8) + b;
}
}
return pixelValues;
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Markup;
using System.Windows.Media.Imaging;
using System.Windows.Media;
using System.Windows;
using System.Windows.Media.Animation;
using System.ComponentModel;
[MarkupExtensionReturnType(typeof(Brush))]
class BilinearGradientBrushExtension:MarkupExtension,INotifyPropertyChanged
{
List<Color> colorMatrix = new List<Color>();
int countX, countY;
private void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public List<Color> ColorMatrix
{
get { return colorMatrix; }
set { colorMatrix = value ; OnPropertyChanged("ColorMatrix"); }
}
public int CountY
{
get { return countY; }
set { countY = value; }
}
public int CountX
{
get { return countX; }
set { countX = value; }
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
int i = ColorMatrix.Count;
int[] pixelValues = GeneratePixelValues();
WriteableBitmap bmp = new WriteableBitmap(countX, countY, 96, 96, PixelFormats.Pbgra32, null);
bmp.WritePixels(new Int32Rect(0, 0, countX, countY), pixelValues, pixelValues.Length, 0);
ImageBrush brush = new ImageBrush(bmp);
return brush;
}
private int[] GeneratePixelValues()
{
int pixelCount = countX * countY;
int[] pixelValues = new int[pixelCount];
for (int i = 0; i < countY; i++)
{
for (int j = 0; j < countX; j++)
{
Color c = ColorMatrix[i * countY + j];
byte a = (byte)c.A;
byte r = (byte)c.R;
byte g = (byte)c.G;
byte b = (byte)c.B;
pixelValues[i*countY +j] = (a << 24) + (r << 16) + (g << 8) + b;
}
}
return pixelValues;
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
对应的xaml:
<l:BilinearGradientBrushExtension x:Name="contur" CountX="2" CountY="2">
<l:BilinearGradientBrushExtension.ColorMatrix>
<Color A="100" R="255" G="0" B="0" />
<Color A="100" R="0" G="255" B="0" />
<Color A="100" R="155" G="155" B="155" />
<Color A="100" R="0" G="0" B="255" />
</l:BilinearGradientBrushExtension.ColorMatrix>
</l:BilinearGradientBrushExtension>
<l:BilinearGradientBrushExtension.ColorMatrix>
<Color A="100" R="255" G="0" B="0" />
<Color A="100" R="0" G="255" B="0" />
<Color A="100" R="155" G="155" B="155" />
<Color A="100" R="0" G="0" B="255" />
</l:BilinearGradientBrushExtension.ColorMatrix>
</l:BilinearGradientBrushExtension>
产生的图片:
不过使用MarkupExtension的方法有个问题,就是产生的图像是静态的,颜色没办法在运行时改变,而且不能使用DependencyProperty,我试过INotifyProperty,会抛异常,暂时没有其他方法。
- BilinearGradientBrushExtension, custom brush in WPF using MarkupExtension instead
- Custom Window Chrome in WPF
- Using Custom Java code in ODI
- WPF之Brush浅见
- wpf brush赋值颜色
- Using INSTEAD OF triggers in SQL Server for DML operations
- Using INSTEAD OF triggers in SQL Server for DML operations
- Save+as+Image+using+DrawingImage()+in+WPF
- Loan Amortization Application in WPF using VC++
- WPF color、brush、string转换
- WPF color、brush、string转换
- Neat Stuff to Do in List Controls Using Custom Draw
- Neat Stuff to Do in List Controls Using Custom Draw
- Neat Stuff to Do in List Controls Using Custom Draw
- custom control的使用方法(Creating and Using custom controls in VC++)
- How to add custom property in custom webpart using VS 2012
- SharePoint 2013 Using PeopleEditor in Custom list or Custom Web Parts
- Custom Command WPF
- Jsp内置对象
- php应用程序的安全不能违反的四条安全规则
- ASP.NET程序中常用的三十三种代码
- 预防感冒简单易行几招
- VS2005(c#)项目调试问题解决方案集锦
- BilinearGradientBrushExtension, custom brush in WPF using MarkupExtension instead
- 盐水漱口可消除口腔异味
- ASP.NET程序中常用代码
- JAVA读取PDF文件
- 二钱铜货
- 学会承担
- 一枚切符
- 转载小集
- 阴兽