Benutzerdefiniertes Steuerelement OnApplyTemplate, das nach dem Rückruf der Abhängigkeitseigenschaft aufgerufen wird

Ich entwickle mein erstes benutzerdefiniertes WPF-Steuerelement und habe einige Probleme. Hier ist eine vereinfachte Version des Codes, den ich derzeit verwende:

using System.Windows;
using System.Windows.Controls;

namespace MyControls
{
    [TemplatePart(Name = "PART_Button", Type = typeof (Button))]
    public class MyControl : Control
    {
        public static readonly DependencyProperty ContentProperty = DependencyProperty.Register("Content", typeof (object), typeof (MyControl), new PropertyMetadata(null, OnLabelPropertyChanged));

        private Button _buttonElement;

        public object Content
        {
            get { return this.GetValue(LabelProperty); }
            set { this.SetValue(ContentProperty, value); }
        }

        static MyControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof (MyControl), new FrameworkPropertyMetadata(typeof (MyControl)));
        }

        private static void OnContentPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            MyControl myControl = sender as MyControl;
            if (myControl != null && myControl._buttonElement != null)
                myControl._buttonElement.Content = e.NewValue;
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            this._buttonElement = this.Template.FindName("PART_Button", this) as Button;
        }
    }
}

Dies ist die Vorlage für mein benutzerdefiniertes Steuerelement:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:MyControls">
    <Style TargetType="{x:Type local:MyControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:MyControl}">
                    <Button x:Name="PART_Button" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

Dann lege ich es in ein Grid und versuche, seine Content-Eigenschaft zu setzen:

<Grid x:Name="layoutRoot">
    <controls:MyControl x:Name="myControl" />
</Grid>

Hier ist der Code dahinter:

using System.Windows;

namespace MyControls
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.InitializeComponent();

            this.myControl.Content = "test";
        }
    }
}

Dies funktioniert nicht. Aus irgendeinem Grund wird der OnContentPropertyChanged-Rückruf vor OnApplyTemplate aufgerufen. Daher wird myControl._buttonElement zu spät zugewiesen und es ist immer noch null, wenn versucht wird, seinen Inhalt festzulegen. Warum passiert das und wie kann ich dieses Verhalten ändern?

Ich muss auch die vollständige Unterstützung für die Entwurfszeit bereitstellen, kann jedoch nicht festlegen, dass mein benutzerdefiniertes Steuerelement zusätzliche Markups akzeptiert, ähnlich wie das Grid-Steuerelement mit ColumnDefinitions:

<Grid x:Name="layoutRoot">
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
</Grid>

Jede Hilfe wäre sehr dankbar!

AKTUALISIEREN

Ich habe ein Dokument gefunden, in dem erklärt wird, warum die OnApplyTemplate-Methode aufgerufen wird, nachdem Steuerelementeigenschaften festgelegt wurden:

http://msdn.microsoft.com/en-us/library/dd351483%28v=vs.95%29.aspx

Die Frage ist also: Wie kann ich die Eigenschaften, die festgelegt wurden (in XAML oder programmgesteuert), und Methoden, die aufgerufen wurden, wenn das Steuerelement nicht initialisiert wurde, nachverfolgen, damit ich sie festlegen / aufrufen kann, wenn die OnApplyTemplate-Methode aufgerufen wird? Wie kann derselbe Rückruf / dieselbe Methode sowohl vor als auch nach der Steuerelementinitialisierung funktionieren, ohne den Code zu duplizieren?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage