这部分提供了怎样使用DrawingVisual对象的概要说明
1. DrawingVisual Object
DrawingVisual
是一个用来渲染
shapes, images,
或者
text
的轻量级的类这个类之所以被认为是轻量级的,是因为它没有提供
layout
或者
event handling
,所以增加了它的运行时性能。正是因为这个原因,描画
backgrounds
和
clip art
是非常理想的。
为了使用
DrawingVisual
对象,需要创建一个对象的
host container
。
host container
对象必须从提供了
layout
和
event handling
的
FrameworkElement
class
继承,而
DrawingVisual
对象没有提供
layout
和
event handling
。
host container
对象不提供任何的显示属性,因为它的主要目的是包含其他的子对象。
当为
visual objects
创建
host container
对象时,需要保存
visual objects
对象的引用到一个
VisualCollection
中,使用
Add
方法添加,参见下面的例子:
// Create a host visual derived from the FrameworkElement class.
// This class provides layout, event handling, and container support for
// the child visual objects.
public class MyVisualHost : FrameworkElement
{
// Create a collection of child visual objects.
private VisualCollection _children;
public MyVisualHost()
{
_children = new VisualCollection(this);
_children.Add(CreateDrawingVisualRectangle());
_children.Add(CreateDrawingVisualText());
_children.Add(CreateDrawingVisualEllipses());
this.MouseLeftButtonUp += new System.Windows.Input.MouseButtonEventHandler(MyVisualHost_MouseLeftButtonUp);
}
3. Creating DrawingVisual Objects
当创建
DrawingVisual
对象时,它不包含任何描画内容。通过得到对象的描画上下文,可以添加
text, graphic,
和
image
内容。对象的描画上下文调用
DrawingVisual
对象的
RenderOpen
方法可以得到。
在描画上下文中描画矩形,使用
DrawingContext
对象的
DrawRectangle
方法,当结束
DrawingContext
的描画内容时,调用
Close
方法关闭描画上下文中
下面的例子中,
DrawingVisual
对象被创建,在它的描画上下文中绘制了一个矩形
// Create a DrawingVisual that contains a rectangle.
private DrawingVisual CreateDrawingVisualRectangle()
{
DrawingVisual dv = new DrawingVisual();
DrawingContext dc = dv.RenderOpen();
Rect r = new Rect(new Point(160, 100), new Size(320, 80));
dc.DrawRectangle(Brushes.LightBlue, (Pen)null, r);
dc.Close();
return dv;
}
4. Creating Overrides for FrameworkElement Members
Host container
对象负责管理
visual objects
的集合。这需要
Host container
实现(
overrides
)从继承
FrameworkElement
class
的一些方法
下面列出了必须override的四个方法
·
ArrangeOverride: Positions the child element and determines size.
·
GetVisualChild: Returns a child at the specified index from the collection of child elements.
·
MeasureOverride: Measures and determines the size in layout required for the child element.
·
VisualChildrenCount: Gets the number of visual child elements within this element.
例子代码:
//<Snippet102a>
// Provide a required override for the VisualChildCount property.
protected override int VisualChildrenCount
{
get { return _children.Count; }
}
// Provide a required override for the GetVisualChild method.
protected override Visual GetVisualChild(int index)
{
if (index < 0 || index > _children.Count)
{
throw new ArgumentOutOfRangeException();
}
return (Visual)_children[index];
}
// Provide a required override for the MeasureOverride method.
protected override Size MeasureOverride(Size availableSize)
{
// Return the value of the parameter.
return base.MeasureOverride(availableSize);
}
// Provide a required override for the ArrangeOverride method.
protected override Size ArrangeOverride(Size finalSize)
{
// Return the value of the parameter.
return base.ArrangeOverride(finalSize);
}
5. Providing Hit Testing Support
Host container
对象虽然没有提供显示的属性,但是提供了
event handling
。这使得可以创建
event handling routine
来处理鼠标事件,例如:
r
elease
鼠标左键,
event handling routine
还可以通过调用
HitTest
方法实现碰撞检测
示例代码:
// Capture the mouse event and hit test the coordinate point value against
// the child visual objects.
void MyVisualHost_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
// Retreive the coordinates of the mouse button event.
Point pt = e.GetPosition((UIElement)sender);
// Initiate the hit test by setting up a hit test result callback method.
VisualTreeHelper.HitTest(this, null, new HitTestResultCallback(myCallback), new PointHitTestParameters(pt));
}
// If a child visual object is hit, toggle its opacity to visually indicate a hit.
public HitTestResultBehavior myCallback(HitTestResult result)
{
if (result.VisualHit.GetType() == typeof(DrawingVisual))
{
if (((DrawingVisual)result.VisualHit).Opacity == 1.0)
{
((DrawingVisual)result.VisualHit).Opacity = 0.4;
}
else
{
((DrawingVisual)result.VisualHit).Opacity = 1.0;
}
}
// Stop the hit test enumeration of objects in the visual tree.
return HitTestResultBehavior.Stop;
}