How can I install custom XAML elements?

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

AND...

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

Everything works fine except for the second element.
I get an error:
Unable to set the value of the Name attribute 'SecondElementName' in the element 'ElementType'. The "ElementType" is under the "ElementType" element, which already has a name registered when it was defined in another area.

Custom grids are defined correctly. The code will compile and run if I select the property ---

 x:Name="SecondElementName" 

--- in Window1.xaml

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

Thanks in advance.

+6
nested wpf xaml grid
source share
3 answers

To know what to do with nested markup objects, the XAML analyzer will, among other things, consider whether the .NET class defines the default “content” property for use as a container for such children. This is done using the "ContentPropertyAttribute".

In your case, since I assume that you want nested objects to enter the grid, and since the children of the grid are part of the Children properties 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 (for example, only allow certain types to be children of your ElementType control), you can instead inherit from IAddChild and implement the AddChild and AddText methods.

Regarding the naming problem, it seems that only those who do not have control can have the names of children in the administrative field. That way, you can have the names of the children inside ElementType.xaml, but not named child elements in another markup where you create an instance of ElementType. I think this is because of how they optimize the logical tree or something like that. On the other hand, management without assistance is control only with code. Therefore, if you turn your class into a plain old empty Grid subclass, it works:

 public class ElementType : Grid { } 

Hooray! Less code!

+5
source share

If you want one inside the other, you 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 do here, but I'm afraid.

+1
source share

If you do not want to modify UserControl, use the attached behavior. So you just need it where the XAML-Compile failed! Only 1 behavior for each UserControl that creates problems.

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; } } 
0
source share

All Articles