我在哪里可以找到有关Brushes如何实现我自己的System.Windows.Media.Brush的足够信息?我可以处理所有可冻结的行李,但是为了让它起作用我需要覆盖的并不是很明显。
是的,所以我并不是说我想使用预定义的画笔。我想扩展System.Windows.Media.Brush,这是一个抽象类。这完全是为了我自己的启发。我甚至不确定我能用什么样的刷子。我只是想了解刷子是如何工作的。如:
public AwesomeBrush : Brush
{
protected override Freezable CreateInstanceCore()
{
return new AwesomeBrush();
}
... // concrete brush stuff
}
答案 0 :(得分:9)
我使用Reflector快速查看了现有的画笔。看起来他们的实现非常封闭,取决于很多internal
管道。虽然可能有可能实现自己的画笔,但似乎它不是受支持的选项。甚至可能是WPF控件与现有画笔紧密相关,并且不适用于自定义画笔。
最有可能实现类似自定义画笔的最佳方法是使用DrawingBrush和一些复杂的绘图逻辑。您可以使用其他画笔从复杂形状中构图画笔,这样可以让您达到所需的目标。
修改后更新
由于这是针对教育的,您可能最好下载Reflector并使用它来查看画笔的工作原理。它们并不意味着是自我实现的,因为它们依赖于程序员通常无法访问的某些internal
类,所以很难这样做。
虽然令人感兴趣的是Brush documentation确实有继承者的注释,以正确的方式从Brush继承。
更多更新
当我四处寻找时,我找到了一种非常简洁的方法来在chinese blog上实现类似的东西。诀窍是使用标记扩展,所以它看起来像一个刷子。实际上,它会根据其属性创建一个新的图像画笔。似乎他得出了相同的结论,即有一些内部类阻止了简单的实现。
答案 1 :(得分:5)
要回答为什么您可能想要自定义画笔的问题,请考虑复杂的几何体,并且您希望使用与形状匹配的渐变填充它,同时从形状的中心径向更改颜色(或任意任意开始)点)。
使用静态填充(几乎消除了所有现有的画笔)无法做到这一点。如果不能一遍又一遍地复制对象并将它们嵌套(并进行脱壳以使其全部看起来正确),用不同的颜色填充每一个,唯一可行的方法是使用可以查看被填充物体的刷子
这在Forms中实际上是可行的。
但看起来在WPF中没有任何办法可以做到这一点,这是不幸的。
事实上,WPF的画笔同时具有惊人的强大功能,令人惊讶地受到限制。它们显然是针对某些概念模型设计的,但我完全不确定它是否超出了一些非常微不足道的视觉效果,并且像往常一样,它被制作得更加复杂,奇怪的(记录不完整的)参数使得它非常简单,有点复杂。
答案 2 :(得分:3)
您不能通过继承System.Windows.Media.Brush
类来创建自定义WPF画笔,因为该类包含内部的抽象成员。
如果使用Reflector查看System.Windows.Media.Brush
类的源代码,您将看到以下内部抽象方法:
internal abstract DUCE.ResourceHandle AddRefOnChannelCore(DUCE.Channel channel);
internal abstract DUCE.Channel GetChannelCore(int index);
internal abstract int GetChannelCountCore();
internal abstract DUCE.ResourceHandle GetHandleCore(DUCE.Channel channel);
internal abstract void ReleaseOnChannelCore(DUCE.Channel channel);
这些必须被覆盖,但不能因为它们是内部的。
注意:编辑我的回答,因为之前的回答是System.Drawing.Brush
,与此问题无关。特别感谢Mikko Rantanen的评论。
答案 3 :(得分:3)
我尝试了每个可能的角度来制作自定义画笔的解决方案,从使用MarkupExtensions到乱用TypeConverter属性,然后它就在我身上:你只需创建一个基于DependencyObject的包装类,创建一个类型为Brush的DependencyProperty,实现您的自定义然后绑定到Brush DependencyProperty。
然后,将自定义画笔放在参考资料
中 <l:CustomBrush x:Key="CustomBrush" Brush="Magenta" />
然后绑定它:
<Line X1="0" Y1="-5" X2="200" Y2="-5"
Stroke="{Binding Source={StaticResource CustomBrush}, Path=Brush}"
StrokeThickness="12"/>
我认为这比MarkupExtension解决方案更好,因为您无法在资源中添加一个,因此每次使用时都必须重新定义自定义设置。
在任何情况下,这似乎都是从任何Wpf对象继承的简单解决方案,并且通过Bindings的灵活性,您还可以绑定到包装的Wpf对象本身的成员。
这是简单的课程:
public class CustomBrush : DependencyObject
{
public CustomBrush()
{
this.Brush = Brushes.Azure;
}
#region Brush DependencyProperty
[BindableAttribute(true)]
public Brush Brush
{
get { return (Brush)GetValue(BrushProperty); }
set { SetValue(BrushProperty, value); }
}
public static readonly DependencyProperty BrushProperty =
DependencyProperty.Register(
"Brush",
typeof(Brush),
typeof(CustomBrush),
new UIPropertyMetadata(null));
#endregion
}