DependencyObject
这个类要有多重要就有多重要,是WPF依赖属性的基础(依赖属性又与其他特性息息相关),在设计WPF类时,如果该对象并不会当做一个元素呈现,且你想拥有绑定等功能,那么继承该类将带来极大的灵活性.
public class TestDP:DependencyObject { public int Number { get { return (int)GetValue(NumberProperty); } set { SetValue(NumberProperty, value); } } public static readonly DependencyProperty NumberProperty = DependencyProperty.Register("Number", typeof(int), typeof(TestDP), new UIPropertyMetadata(0)); }
通过GetValue和SetValue方法使用DP属性,如果你不想继承该类,那么还有一个选择,那就是附加属性,可能你的很多类已经设计好了,已经有了基类.
public class TestAttachDP { public static int GetNumber(DependencyObject obj) { return (int)obj.GetValue(NumberProperty); } public static void SetTimeLineSynchronousHost(DependencyObject obj, int value) { obj.SetValue(NumberProperty, value); } public static readonly DependencyProperty NumberProperty = DependencyProperty.RegisterAttached("Number", typeof(int), typeof(TestAttachDP), new UIPropertyMetadata(0)); }
依赖属性是构建灵活的WPF系统的基础
System.Windows.Media.Visual
该类构建了一个视觉树的概念,并提供了一些与绘图有关的属性,但与其本身WPF绘图引擎无关,其只提供属性.
有那么一种元素其本身并不会绘制任何图形,但其却还是存在视觉树中.它的存在可以用作数据存储或者当做与布局无关的容器使用.
实际中继承此类的意义不大,因为其不具备绘图功能.其意义在于打下扎实的基类基础
public class NoRenderVisual:Visual { protected override int VisualChildrenCount { get { return base.VisualChildrenCount; } } protected override Visual GetVisualChild(int index) { return base.GetVisualChild(index); } }
添加这样的视觉树意义不大,我们也无需继承重写,因为内置有更好的选择
System.Windows.Media.ContainerVisual
一个继承自Visual的类,使得其有一个基本的容器(Children)结构,该类充当视觉树容器更加适合,否则你只能选择Visual来重写了,实际上该类你可能并不常用,由于其自身并没有布局系统,即使添加了元素也无法呈现,作为辅助使用
public class OwnContainerVisual:ContainerVisual { public OwnContainerVisual() { var element = new Button(){Width = 100,Height = 20,Content = "hello"}; this.Children.Add(element); } }现在不再使用AddVisualChild方法添加Visual,而是使用Children集合
System.Windows.Media.DrawingVisual
DrawingVisual是真正一个轻量级并派的上用场的类,因为其拥有RenerOpen方法,获取DrawingContext,这样就开始画图了
public class RectanlgeVisual : DrawingVisual { public RectanlgeVisual() { using (var dc=this.RenderOpen()) { dc.DrawRectangle(Brushes.Red, null, new Rect(0, 0, 100, 100)); } } }
何谓轻量级即,只有最基础的绘图功能,但没有相关的事件,布局,模板等特性,但是效率会更好.复杂度会更高.使用方面不是特别的方便.
System.Windows.UIElement.UIElement
如果说DrawingVisual是轻量级,那么UIElement就是重量级的了,到了这一步元素拥有的基础的事件和布局系统,可以用过重写OnRender方法重绘控件的外观
public class RectangleUIElement:UIElement { public RectangleUIElement() { Brush = Brushes.Red; } protected override void OnMouseDown(MouseButtonEventArgs e) { base.OnMouseDown(e); Brush = Brushes.Green; //re-render this.InvalidateVisual(); } protected override void OnMouseUp(MouseButtonEventArgs e) { base.OnMouseUp(e); Brush = Brushes.Red; //re-render this.InvalidateVisual(); } public Brush Brush { get; set; } protected override void OnRender(DrawingContext drawingContext) { drawingContext.DrawRectangle(Brush, null, new Rect(0, 0, 100, 100)); base.OnRender(drawingContext); } }
就此打住,接下来的目标还是研究其布局系统