Template Binding in Control template Template Binding in Control template wpf wpf

Template Binding in Control template


I'd suggest using dynamic resources, e.g. define the template as follows:

<ControlTemplate x:Key="buttonTemplate" TargetType="Button">    <Border CornerRadius="5"  Margin="15" Cursor="Hand">        <StackPanel Orientation="Horizontal" Background="Yellow">            <Image Source="{DynamicResource ResourceKey=Img}" Height="100" Width="100" Margin="5"></Image>            <Label Content="{TemplateBinding Content}" Background="Transparent" Margin="2"></Label>        </StackPanel>    </Border></ControlTemplate>

And use it like this:

<Button Content="Button" Template="{StaticResource ResourceKey=buttonTemplate}">    <Button.Resources>        <ImageSource x:Key="Img">SomeUri.png/</ImageSource>    </Button.Resources></Button>


TemplateBinding is a lightweight "binding", it doesn't support some features of traditional Binding, such as automatically type conversion using the known type converters associated with the target property (such as converting the string URI into a BitmapSource instance).

The following code can work properly:

<Window x:Class="GridScroll.Window2"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    Title="Window2"><Window.Resources>    <Style TargetType="{x:Type Button}" x:Key="ButtonStyle">        <Setter Property="Template">            <Setter.Value>                <ControlTemplate TargetType="Button">                    <Border CornerRadius="5"  Margin="15" Cursor="Hand" Background="Red">                        <StackPanel Orientation="Horizontal" Background="White">                            <Image Name="Img" Source="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}" Margin="5"></Image>                            <Label Content="{TemplateBinding Content}" Margin="2"></Label>                        </StackPanel>                    </Border>                </ControlTemplate>            </Setter.Value>        </Setter>    </Style></Window.Resources><StackPanel Orientation="Horizontal">    <Button Style="{StaticResource ButtonStyle}" Tag="a.jpeg" Content="a"/>    <Button Style="{StaticResource ButtonStyle}" Tag="b.png" Content="b"/></StackPanel>


You haven't really said how you expect consumers of your button to set the source. You could use the Button.Tag property, for example, and then bind to that in your template. Or you could define your own control:

public class ImageButton : Button{    // add Source dependency property a la Image}

And then the template:

<ControlTemplate TargetType="ImageButton">    <Border CornerRadius="5"  Margin="15" Cursor="Hand">        <StackPanel>            <Image Name="Img" Style="{StaticResource ImageStyle}" Source="{TempateBinding Source}" Height="100" Width="100" Margin="5"></Image>            <Label Content="{TemplateBinding Content}" Background="Transparent" Margin="2"></Label>        </StackPanel>    </Border></ControlTemplate>