Reputation: 393
I have my custom control derived from Control class. I want to create dependency property of another control (for example, button) and place it in ControlTemplate (so button can be placed in xaml and MyControl's users can subscribe to it's events etc.). May someone tell me, how can I do it?
Here is result code example:
public class MyControl: Control
{
static MyControl( )
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl), new FrameworkPropertyMetadata(typeof(MyControl)));
}
public static readonly DependencyProperty MyButtonProperty =
DependencyProperty.Register("MyButton",
typeof(Button),
typeof(MyControl),
new PropertyMetadata(default(Button)));
public Button MyButton
{
get
{
return (Button) GetValue(MyButtonProperty);
}
set
{
SetValue(MyButtonProperty, value);
}
}
}
xaml:
<ControlTemplate TargetType="{x:Type lib:MyControl}">
<Canvas>
<Border Child="{TemplateBinding MyButton}">
</Border>
</Canvas>
</ControlTemplate>
Upvotes: 3
Views: 240
Reputation: 178650
Your control's template can declare a dependency on child controls via the TemplatePartAttribute
. You then get an instance of that dependency in your OnApplyTemplate
method.
[TemplatePart(Name = PartButton, Type = typeof(ButtonBase))]
public class MyControl : Control
{
private const string PartButton = "PART_Button";
private ButtonBase buttonPart;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this.buttonPart = GetTemplateChild(PartButton) as ButtonBase;
}
}
Your control template would then look something like:
<Style TargetType="MyControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="MyControl">
<Border ...>
<Button x:Name="PART_Button" .../>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style
Note that this.buttonPart
could be null
if the template did not include an appropriately named ButtonBase
within it. You should strive to ensure your control still works when template parts are missing.
Upvotes: 3