假设我想创建一个直接从UIElement
继承的类,并且能够包含一个或多个[外部添加的]UIElement
作为子级,就像Panel
和其他容器控件一样。让类以某种形式容纳UIElement
的集合显然很容易,但我如何使它们与我的类一起显示/渲染呢?
我认为它们必须以某种方式作为我自己的UIElement
的子级添加到视觉树中(或者,可能通过VisualTreeHelper.GetDrawing
手动渲染它们,并使用OnRender
的DrawingContext
?但这似乎很笨拙)。
我不想知道我可以或应该继承更多现成的控件,如FrameworkElement
、Panel
、ContentControl
等(如果有什么不同的话,我想知道它们是如何实现外部添加的子元素的显示/呈现的,如果适用的话)。
我有自己的理由想要在层次结构中尽可能高,所以请不要给我任何关于为什么"符合XAML/WPF框架"等是件好事的讲座。
以下类提供了子元素布局和渲染方面的绝对最小值:
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);
}
}
}
不需要具有UIElementCollection。另一种实现方式可能是这样的:
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
}