WPF的逻辑树与视觉树(3)Visual呈现

    这篇就点到为止,挑重点讲

绘图方式有两种


1.继承UIElement,重写OnRender方法

public partial class Window5 : Window
{
    public Window5()
    {
        InitializeComponent();
        this.Content = new RectangleElement();
    }
}

public class RectangleElement : UIElement
{
    protected override void OnRender(DrawingContext drawingContext)
    {
        drawingContext.DrawRectangle(Brushes.Red, null, new Rect(0, 0, 100, 20));
        base.OnRender(drawingContext);
    }
}

2.DrawingVisual 轻量级绘图,只提供显示和测试点击功能,DrawingVisual继承自ContainerVisual,所以其也是Visual集合容器

public class RectangleElement : UIElement
{
    DrawingVisual visual; 
    public RectangleElement()
    {
        visual = new DrawingVisual();
        var drawingContext = visual.RenderOpen();
        drawingContext.DrawRectangle(Brushes.Red, null, new Rect(0, 0, 100, 20));
        drawingContext.Close();
        this.AddVisualChild(visual);
    }

    protected override Visual GetVisualChild(int index)
    {
        return visual;
    }

    protected override int VisualChildrenCount
    {
        get
        {
            return 1;
        }
    }
}


DrawingVisual无法单独存在,必须放在一个容器中(需要有布局系统)呈现.我们看到每次添加一个Visual的时候,总还是难免要实现GetVisualChild和VisualChildrenCount这两个成员.除了ContainerVisual这些轻量级的对象,Panel会帮我们做掉上面这些工作.但基类却变成了UIElement.事实上当添加Visual以后,同时还要计算布局的尺寸,所以有必要的话,可以对UIElement或者FrameworkElement重写以上两个成员。因为有时候我们只需要一次布局和添加多个Visual,以提升性能

重写默认窗体的视觉树

public partial class Window5 : Window
{
    DrawingVisual dv;
    public Window5()
    {
        InitializeComponent();
        dv = new DrawingVisual();
    }

    protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
    {
        var drawingContext = dv.RenderOpen();
        drawingContext.DrawRectangle(Brushes.Red, null, new Rect(0, 0, this.ActualWidth, ActualHeight));
        drawingContext.Close();
        base.OnRenderSizeChanged(sizeInfo);
    }

    protected override Visual GetVisualChild(int index)
    {
        return dv;
    }
}
重写后的窗体视觉树达到了最小化
image

上面看到并没有调用AddVisualChild方法,而视觉树的判断依据还是根据GetVisualChild和VisualChildrenCount,不过还是乖乖地加上AddVisualChild方法以免出现什么问题.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值