[英]How do I make a custom UIElement-derived class that contains (and displays) other UIElements as children?
Let's say I want to make a class that inherits directly from UIElement
and is able to contain one or more [externally added] UIElement
s as children - like Panel
s and other container controls. 假设我想创建一个直接从UIElement
继承的类,并且能够包含一个或多个[外部添加的] UIElement
作为子项 - 比如Panel
和其他容器控件。 It's obviously easy to have the class house a collection of UIElement
s in some form or other, but how do I get them to be displayed / rendered along with my class? 很容易让班级以某种形式存放UIElement
的集合,但是如何让它们与我的班级一起展示/呈现呢?
I assume they must be added to the visual tree as children of my own UIElement
in some way (or, possibly, render them manually à la going via VisualTreeHelper.GetDrawing
and do it using OnRender
's DrawingContext
? But that seems clumsy). 我认为它们必须以某种方式作为我自己的UIElement
子项添加到可视化树中(或者,可能通过VisualTreeHelper.GetDrawing
手动渲染它们并使用OnRender
的DrawingContext
渲染?但这看起来很笨拙)。
I do not want to know that I can - or should - inherit from more ready-made controls, like FrameworkElement
, Panel
, ContentControl
etc (if anything, I want to know how they are implementing the displaying / rendering of externally added child elements, where applicable). 我不想知道我能-或者应该-从多个现成的控制继承,像FrameworkElement
, Panel
, ContentControl
等等(如果有的话,我想知道他们是如何实现外部添加子元素的显示/渲染,如适用)。
I have my reasons for wanting to be as high up in the hierarchy as possible, so please don't give me any lectures on why it is a good thing to be XAML / WPF Framework 'compliant' etc. 我有理由希望在层次结构中尽可能高,所以请不要给我任何讲座,说明为什么XAML / WPF框架“符合”等等是件好事。
The following class provides the absolute minimum in terms of layout and rendering of child elements: 以下类在子元素的布局和呈现方面提供绝对最小值:
public class UIElementContainer : UIElement
{
private readonly UIElementCollection children;
public UIElementContainer()
{
children = new UIElementCollection(this, null);
}
public void AddChild(UIElement element)
{
children.Add(element);
}
public void RemoveChild(UIElement element)
{
children.Remove(element);
}
protected override int VisualChildrenCount
{
get { return children.Count; }
}
protected override Visual GetVisualChild(int index)
{
return children[index];
}
protected override Size MeasureCore(Size availableSize)
{
foreach (UIElement element in children)
{
element.Measure(availableSize);
}
return new Size();
}
protected override void ArrangeCore(Rect finalRect)
{
foreach (UIElement element in children)
{
element.Arrange(finalRect);
}
}
}
It is not required to have a UIElementCollection. 不需要具有UIElementCollection。 An alternative implementation could look like this: 另一种实现可能如下所示:
public class UIElementContainer : UIElement
{
private readonly List<UIElement> children = new List<UIElement>();
public void AddChild(UIElement element)
{
children.Add(element);
AddVisualChild(element);
}
public void RemoveChild(UIElement element)
{
if (children.Remove(element))
{
RemoveVisualChild(element);
}
}
// plus the four overrides
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.