自定义UIElement可以实现IList <uielement>并直接分配子项(在XAML中)吗?</uielement>

时间:2013-12-11 17:07:00

标签: wpf xaml collections panel children

场景:我有一系列自定义UIElements(事实上,我已将所有标准WPF FrameworkElements替换为更轻,更高效的对应物),用于仅限定制布局系统用那些。它们都继承自一个名为Surface的类(后者又是UIElement的直接后代)。

我现在想知道我的Panel版本(让我们称之为SurfacePanel)是否可以简单地实现IList<Surface>并允许添加子Surface个元素直接到它,而不是Children属性(与常规WPF面板一样),XAML中的

为了说明 - 在代码隐藏中,我现在可以这样做:

SurfacePanel.Add(child);

从那以后,我希望能够在XAML中做到这一点:

<SurfacePanel>
    <child />
</SurfacePanel>

但是XAML似乎要求我有这样的代码隐藏模式:

SurfacePanel.Children.Add(child)

(我真的不需要这些控件来支持XAML在运行时环境中工作,但在测试和原型设计时,我喜欢使用我的UI控件和#34; XAML友好&#34;所以我可以受益来自VS中的视觉设计师(以及属性窗格等),如果只是作为预览窗口)。

由于我的控件继承自UIElement(并且具有适当的测量/排列/渲染覆盖等等),所以当它们穿上时会运行得很好,比如常规Canvas或{{1 }}。但是当我在标记中添加子项时,VS XAML解析器对我的Grid(实现SurfacePanel不太满意。它表示&#34;无法将内容添加到类型&#34; SurfacePanel&#34;&#34;的对象中。

我知道如果我添加适当类型的IList<Surface>属性并向Children类(SurfaceCanvas)添加属性,它将起作用。但由于[ContentProperty("Children")]本身就是一个能够完成同样事情的集合,有没有办法让XAML“得到它”?


编辑:

我可以解决XAML&#39;合规问题&#39;通过在SurfacePanel上添加Children属性,只返回其内部SurfacePanel,但随后在其上添加和删除元素会直接绕过连接子元素的内部逻辑。

如果内部列表是List,我可以按照传统方式进行,并在ObservableCollection事件处理程序中进行连接 - 但基本上是将CollectionChanged集成到小组直接是为了避免......


编辑2:

这&#34;工作&#34; (但绕过接线):

IList

我无法返回[ContentProperty("Children")] public class SurfacePanel : Surface, IList<Surface> { private readonly List<Surface> _children = new List<Surface>(); public List<Surface> Children { get { return _children; } } } ,因为this不是SurfacePanel,而是List<Surface>

如果我将属性更改为

IList<Surface>

即使使用以下XAML(但不是 public IList<Surface> Children { get { return this; } } ),我收到错误消息:

<m:SurfacePanel/>

错误消息是

<m:SurfacePanel> </m:SurfacePanel>

1 个答案:

答案 0 :(得分:3)

同时实现IList并声明Children属性,如下所示:

[ContentProperty("Children")]
public class SurfacePanel : Surface, IList, IList<Surface>
{
    public IList Children
    {
        get { return this; }
    }

    ...
}