UPDATE:
Instead of letting your property "push" the value changes to the elements in your template, looking for parts, you should instead bind the template to the properties of the template to be masked.
This is usually done using presenters in the template, for example. ContentPresenter binds to the property designated as “content” (it recognizes this name by looking for the [ContentProperty] attribute) and using the bindings in your template that use TemplateBinding or TemplatedParent to connect to the properties in your user control.
Then there is no question of what order you set for your properties and when the template is applied ... because it is a template that provides a "view" of the data / properties set on your control.
The user control must really know and interact with the "parts" if it needs to provide certain behavior / functionality, for example. connecting the event of clicking on the "part" button.
In this case, instead of setting Content in the constructor in the code, you should bind your template to the property. The example below showed how this was done using the Content property.
Alternatively, you can pull the properties more explicitly, for example. it could be inside your template.
<Label Content="{TemplateBinding MyPropertyOnMyControl}" ..... <Button Content="{TemplateBinding AnotherPropertyOnMyControl}" .....
I think it would be better to assign your “content” using the [ContentProperty] attribute, and then use ContentPresenter in your template so that it can be entered inside your button, instead of connecting Content DependencyProperty. (if you inherit ContentControl, this ensures the behavior of "content").
[TemplatePart(Name = "PART_Button", Type = typeof (Button))] public class MyControl : Control [ContentProperty("Content")]
and
<ControlTemplate TargetType="{x:Type local:MyControl}"> <Button x:Name="PART_Button"> <ContentPresenter/> </Button> </ControlTemplate>
As for what you want to specify some development-time data through XAML, for example, Grid does with ColumnDefinition .... well, that just uses the Property Element syntax to specify elements to populate the typed IList / ICollection property.
So, just create your own property, which may contain a collection of the type that you accept, for example.
public List<MyItem> MyItems { get; set; }