Reputation: 732
I have a user control which I'd like to be used like so:
// MainPage.xaml
<my:MyControl Data="10" />
<!-- or -->
<my:MyControl Data="{Binding SomeData}" />
It's codebind is this:
public partial class MyControl : UserControl
{
public MyControl() {
InitializeComponent();
}
public const string DataPropertyName = "Data";
public int Data
{
get
{
return (int)GetValue(DataProperty);
}
set
{
SetValue(DataProperty, value);
}
}
public static readonly DependencyProperty DataProperty = DependencyProperty.Register(
DataPropertyName,
typeof(int),
typeof(MyControl),
new PropertyMetadata(10);
}
It's xaml portion is this:
<UserControl>
<!-- omitted namespaces etc. -->
<Grid x:Name="LayoutRoot">
<Button x:Name="myButton" Content="{Binding Data}">
<Button.Style>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<TextBlock Text="{TemplateBinding Content}" />
</ControlTemplate>
</Setter.Value>
</Button.Style>
</Button>
</Grid>
</UserControl>
The crucial line, in usercontrol's xaml part is:
<Button x:Name="myButton" Content="{Binding Data}">
I'd like to bind this Button's Content property to the UserControl's property (Data), while still retaining the ability to set values on it from outside (<my:MyControl Data="10" />
)
The problem is, that when I use binding - <Button x:Name="myButton" Content="{Binding Data}">
- it doesn't work (The templatebinding doesnt pick any values)
It works however, if I set the values manually i.e - <Button x:Name="myButton" Content="12">
Upvotes: 3
Views: 1998
Reputation: 139758
If you want to bind to your "own" dependency property inside a UserControl
you need to add a x:Name
to your UserControl
and use it as the ElementName
in your binding.
<UserControl x:Name="myControl">
<!-- omitted namespaces etc. -->
<Grid x:Name="LayoutRoot">
<Button x:Name="myButton"
Content="{Binding Data, ElementName=myControl}">
</Button>
</Grid>
</UserControl>
To make the Template
also work:
Instead of the TemplateBinding
you need to use the RelativeSource TemplatedParent
sysntax, because you need to set the Mode=OneWay
(TemplateBinding uses Mode=OneTime
for performance reasons by default but in your scenario you need Mode=OneWay
)
<Style TargetType="Button">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<TextBlock Text="{Binding Path=Content, Mode=OneWay,
RelativeSource={RelativeSource TemplatedParent}}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
Upvotes: 6