如何嵌套自定义 XAML 元素? [英] How Can I Nest Custom XAML Elements?

查看:17
本文介绍了如何嵌套自定义 XAML 元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="Window1">
    <Grid>
        <local:ElementType x:Name="FirstElementName">
            <local:ElementType x:Name="SecondElementName" Grid.Column="1" Grid.Row="1" />
        </local:ElementType>
    </Grid>
</Window>  

这是在其他文件中...

And this is in other files ...

<Grid x:Name="InternalElementName" x:Class="WpfApplication1.ElementType"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1">
</Grid>  

还有……

public partial class ElementType : System.Windows.Controls.Grid { }  

一切正常,除了第二个元素.
我得到错误:
无法在元素ElementType"上设置名称属性值SecondElementName".ElementType"在元素ElementType"的范围内,当它在另一个范围内定义时,它已经注册了一个名称.

Everything works fine, except the second element.
I get the error:
Cannot set Name attribute value 'SecondElementName' on element 'ElementType'. 'ElementType' is under the scope of element 'ElementType', which already had a name registered when it was defined in another scope.

自定义网格定义正确.如果我取出属性,代码将编译并运行 ---

The custom grids are defined properly. The code will compile and run if I take out the property ---

x:Name="SecondElementName"  

---在Window1.xaml中

--- in Window1.xaml

是什么导致了这个错误?我该如何解决?我需要将这些自定义网格中的一个嵌套在另一个网格中,并且我需要它们的名称,以便我可以将它们绑定到单独的数据.

What is causing this error? How do I get around it? I need to nest one of these custom grids inside the other one, and I need names on both of them so I can bind them to seperate data.

提前致谢.

推荐答案

为了知道如何处理嵌套标记对象,XAML 解析器将查看 .NET 类是否定义了默认的内容"" 用作此类儿童的容器的财产.这是通过ContentPropertyAttribute"完成的.

In order to know what to do with nested markup objects, the XAML parser will, among other things, look at whether the .NET class defines a default "content" property to use as a container for such children. This is done with the "ContentPropertyAttribute".

在您的情况下,因为我猜您希望嵌套对象进入网格内部,并且由于网格的子对象进入儿童"属性集合,您只需要执行以下操作:

In your case, since I guess you want nested objects to go inside the Grid, and since the children of a grid go in the "Children" property collection, you just need to do the following:

[ContentProperty("Children")]
public partial class ElementType : Grid
{
    // your code here...
}

如果在向控件添加子控件时需要执行一些逻辑(例如,仅允许某些类型成为 ElementType 控件的子控件),则可以改为从 IAddChild 继承,并实现 AddChild 和 AddText 方法.

If you need to do some logic when adding children to your control (e.g. only allow certain types to be children of your ElementType control), you can instead inherit from IAddChild, and implement the AddChild and AddText methods.

至于命名问题,似乎只有无视控件才能在实例化范围内命名子项.所以基本上,您可以在 ElementType.xaml 中命名子项,但不能在您实例化 ElementType 的其他标记中命名子项.我想这是因为他们优化逻辑树或其他东西的方式.另一方面,无外观控件是只有代码的控件.所以如果你把你的类变成一个简单的旧的 Grid 空子类,它就可以工作:

As for the naming problem, it seems that only lookless controls can have named children in an instanced scope. So basically, you can have named children inside ElementType.xaml, but not named children in other markup where you instantiate ElementType. I guess it's because of the way they optimize the logical tree or something. A lookless control, on the other hand, is a control with only code. So if you turn your class into a plain old empty subclass of Grid, it works:

public class ElementType : Grid
{
}

耶!更少的代码!

这篇关于如何嵌套自定义 XAML 元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆