场景:我有一系列自定义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>
答案 0 :(得分:3)
同时实现IList
并声明Children
属性,如下所示:
[ContentProperty("Children")]
public class SurfacePanel : Surface, IList, IList<Surface>
{
public IList Children
{
get { return this; }
}
...
}