ich meine erste WPF-Steuerelement zu entwickeln und ich bin vor einige Probleme, hier ist eine vereinfachte Version des Codes ich zur Zeit mit:Custom Control OnApplyTemplate nach Abhängigkeitseigenschaft Callback
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 meine benutzerdefinierte Steuerung:
<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>
ich es dann in einem Gitter setzen und versuchen, seine Content-Eigenschaft zu setzen:
<Grid x:Name="layoutRoot">
<controls:MyControl x:Name="myControl" />
</Grid>
Hier ist der Code hinter:
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 Grunde der OnContentPropertyChanged Rückruf vor OnApplyTemplate genannt wird, so myControl._buttonElement zu spät zugewiesen ist und es ist immer noch null, wenn man versucht seinen Inhalt zu setzen. Warum passiert das und wie kann ich dieses Verhalten ändern?
Ich brauche auch vollen Entwurfszeit-Unterstützung zur Verfügung zu stellen, aber ich kann nicht einen Weg zu machen, meine individuelle Kontrolle übernimmt einige zusätzliche Markup, ähnlich wie das Grid-Steuerelement funktioniert mit ColumnDefinitions finden:
<Grid x:Name="layoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
</Grid>
Jede Hilfe wäre sehr geschätzt!
UPDATE
fand ich ein Dokument, das, warum die OnApplyTemplate Methode erklärt, nachdem die Steuerung aufgerufen wird properies eingestellt:
http://msdn.microsoft.com/en-us/library/dd351483%28v=vs.95%29.aspx
Die Frage ist also: Wie kann ich den Überblick über das halten Eigenschaften, die festgelegt werden (in XAML oder programmgesteuert) und Methoden, die aufgerufen werden, wenn das Steuerelement nicht initialisiert wurde, sodass ich sie beim Aufruf der OnApplyTemplate-Methode festlegen/aufrufen kann? Wie kann derselbe Callback/Methode vor und nach der Steuerungsinitialisierung funktionieren, ohne den Code zu duplizieren?
haben Sie versucht, base.OnApplyTemplate() aufzurufen; nach Ihrem Template.FIndName (..)? – sam