WPF Tutorial - Using A Visual Collection

本文介绍如何利用 WPF 中的 VisualCollection 实现 Adorner 的子元素显示功能,通过创建自定义 AdornerContentPresenter 类,使得 Adorner 能够拥有并显示 Visual 子元素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

While WPF and XAML make the common 90% of UI programming quite easy, sometimes it gets a little odd in those other 10%. For instance - the visual tree. Most of the time it works great, and you never need to do anything special with it. But what about when you specifically want to give a user control children? Or maybe you want to give an adorner an actual visual child, instead of using OnRender? It isn't really obvious right away how to go about doing that.

But while it is not obvious, it is possible - and so today we are going to take a look at using VisualCollection to do those things. Specifically, we are going to create an Adorner to be used in an AdornerLayer that accepts a Visual as content. This is not possible right out of the gate, because Adorners don't have any built in way to have Visual children, and we can't use any of the normal controls that do (PanelContentPresenter, etc...), because only Adorners can be placed on an AdornerLayer.

Now, the example we are going to build today to use this adorner that can present content is pretty silly, but it is actually quite useful. I've used it a number of times for drag and drop (giving visual representations of what is being dragged and what will happen when it drops). Ok, now for some code:

public class AdornerContentPresenter : Adorner { private VisualCollection _Visuals; private ContentPresenter _ContentPresenter; public AdornerContentPresenter(UIElement adornedElement) : base(adornedElement) { _Visuals = new VisualCollection(this); _ContentPresenter = new ContentPresenter(); _Visuals.Add(_ContentPresenter); } public AdornerContentPresenter(UIElement adornedElement, Visual content) : this(adornedElement) { Content = content; } protected override Size MeasureOverride(Size constraint) { _ContentPresenter.Measure(constraint); return _ContentPresenter.DesiredSize; } protected override Size ArrangeOverride(Size finalSize) { _ContentPresenter.Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height)); return _ContentPresenter.RenderSize; } protected override Visual GetVisualChild(int index) { return _Visuals[index]; } protected override int VisualChildrenCount { get { return _Visuals.Count; } } public object Content { get { return _ContentPresenter.Content; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值