<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>
这是在其他档案......
<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'的范围内,在另一个范围内定义时已经注册了名称。
正确定义了自定义网格。如果我取出属性---
,代码将编译并运行x:Name="SecondElementName"
---在Window1.xaml
中导致此错误的原因是什么?我该如何解决这个问题?我需要将其中一个自定义网格嵌套在另一个中,我需要两个名称,以便将它们绑定到单独的数据。
提前致谢。
答案 0 :(得分:5)
为了知道如何处理嵌套标记对象,XAML解析器将查看.NET类是否定义了一个默认的“content”属性,以用作此类子对象的容器。这是通过“ContentPropertyAttribute”完成的。
在您的情况下,因为我猜您希望嵌套对象进入网格内部,并且由于网格的子项位于“Children”属性集合中,您只需执行以下操作:
[ContentProperty("Children")]
public partial class ElementType : Grid
{
// your code here...
}
如果在向控件添加子项时需要执行某些逻辑(例如,只允许某些类型为ElementType控件的子项),则可以继承IAddChild,并实现AddChild和AddText方法。
至于命名问题,似乎只有无外观控件可以在实例范围内具有命名子项。基本上,您可以在ElementType.xaml中命名子项,但在实例化ElementType的其他标记中不能命名子项。我想这是因为他们优化逻辑树或其他东西的方式。 另一方面,无外观控制是仅具有代码的控件。因此,如果您将您的类转换为Grid的一个普通的旧空子类,它就可以工作:
public class ElementType : Grid
{
}
耶!更少的代码!
答案 1 :(得分:1)
如果你想要一个在另一个中,你想把内在的那个放在第一个的Content属性中:
<local:ElementType x:Name="FirstElementName">
<local:ElementType.Content>
<local:ElementType x:Name="SecondElementName" Grid.Column="1" Grid.Row="1" />
</local:ElementType.Content>
</local:ElementType>
另外,我不确定你在这里要做什么,但我担心。
答案 2 :(得分:0)
如果您不想更改UserControl,请使用附加行为。所以你只需要它,XAML-Compile失败了!每个UserControl只有一个行为会造成麻烦。
在XAML中:
<preview:PreviewControl>
<i:Interaction.Behaviors>
<behaviors:UserControlNameBehavior Name="ICanSetNames"/>
</i:Interaction.Behaviors>
</preview:PreviewControl>
在C#中:
public class UserControlNameBehavior : Behavior<UserControl>
{
public string Name { get; set; }
protected override void OnAttached()
{
this.AssociatedObject.Loaded += OnLoaded;
base.OnAttached();
}
private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
{
this.AssociatedObject.Name = this.Name;
}
}