How Can I Nest Custom XAML Elements?

删除回忆录丶 提交于 2019-12-05 07:10:53

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...
}

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.

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
{
}

Yay! Less code!

Anderson Imes

If you want one within the other, you'd want to put the inner one in the Content property of the first:

<local:ElementType x:Name="FirstElementName">
    <local:ElementType.Content>
        <local:ElementType x:Name="SecondElementName" Grid.Column="1" Grid.Row="1" />
    </local:ElementType.Content>
</local:ElementType>

Also, I'm not sure what you are trying to accomplish here, but I fear it.

If you don't want to change the UserControl, use a attached behavior. So you just need it there, where the XAML-Compile failed! Only 1 behavior for every UserControl which makes trouble.

in XAML:

 <preview:PreviewControl>
    <i:Interaction.Behaviors>
       <behaviors:UserControlNameBehavior Name="ICanSetNames"/>
    </i:Interaction.Behaviors>
 </preview:PreviewControl>

in 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;
        }
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!