Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TemplateBinding to DependencyProperty on a custom control not working

Currently, I'm working on a simple custom button that uses user supplied images as a background for the pressed and normal states. I've a lot of buttons so I decided to write a custom button and implement two properties for the pressed and normal states' pictures.

Here is the code I'm using

public partial class ThemeableButton : Button {     public ThemeableButton()     {         InitializeComponent();     }       public static readonly DependencyProperty PressedContentBackgroundSourceProperty = DependencyProperty.Register(                     "PressedContentBackgroundSource", typeof(ImageSource), typeof(ThemeableButton), null);     public ImageSource PressedContentBackgroundSource     {         get { return (ImageSource)GetValue(PressedContentBackgroundSourceProperty); }         set         {             (value as BitmapImage).CreateOptions = BitmapCreateOptions.BackgroundCreation;              SetValue(PressedContentBackgroundSourceProperty, value);         }     }       public static readonly DependencyProperty NormalContentBackgroundSourceProperty =         DependencyProperty.Register("NormalContentBackgroundSource", typeof(ImageSource), typeof(ThemeableButton), null);      public ImageSource NormalContentBackgroundSource     {         get { return (ImageSource)GetValue(NormalContentBackgroundSourceProperty); }         set         {             (value as BitmapImage).CreateOptions = BitmapCreateOptions.BackgroundCreation;             SetValue(NormalContentBackgroundSourceProperty, value);         }     } } 

I wrote the style for this button as follows

        <Style x:Key="ThemeableButtonTemplate" TargetType="MJbox_UIComponents_Controls:ThemeableButton">         <Setter Property="Background" Value="Transparent"/>         <Setter Property="BorderBrush" Value="{StaticResource PhoneForegroundBrush}"/>         <Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>         <Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>         <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilySemiBold}"/>         <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>         <Setter Property="Padding" Value="0"/>         <Setter Property="Template">             <Setter.Value>                 <ControlTemplate TargetType="MJbox_UIComponents_Controls:ThemeableButton">                     <Grid>                         <VisualStateManager.VisualStateGroups>                             <VisualStateGroup x:Name="CommonStates">                                 <VisualState x:Name="Normal">                                     <Storyboard>                                         <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Source" Storyboard.TargetName="ButtonBackground">                                             <DiscreteObjectKeyFrame KeyTime="0" Value="{TemplateBinding NormalContentBackgroundSource}">                                             </DiscreteObjectKeyFrame>                                         </ObjectAnimationUsingKeyFrames>                                     </Storyboard>                                 </VisualState>                                 <VisualState x:Name="Pressed">                                     <Storyboard>                                         <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Source" Storyboard.TargetName="ButtonBackground">                                             <DiscreteObjectKeyFrame KeyTime="0" Value="{TemplateBinding PressedContentBackgroundSource}">                                             </DiscreteObjectKeyFrame>                                         </ObjectAnimationUsingKeyFrames>                                     </Storyboard>                                 </VisualState>                             </VisualStateGroup>                         </VisualStateManager.VisualStateGroups>                         <Border BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="0">                             <Image x:Name="ButtonBackground" Stretch="None" Source="{TemplateBinding NormalContentBackgroundSource}"/>                         </Border>                            </Grid>                 </ControlTemplate>             </Setter.Value>         </Setter>     </Style> 

I tried a simple example

<Controls:ThemeableButton Style="{StaticResource ThemeableButtonTemplate}" x:Name="btnDidntNeedIt" NormalContentBackgroundSource="{Binding Source={StaticResource DefaultTheme}, Path=DidntHaveButtonUnselected}"                                    PressedContentBackgroundSource="{Binding Source={StaticResource DefaultTheme}, Path=DidntHaveButtonSelected}"          /> 

but the image is not showing, I tried by removing the TemplateBinding from the style and replaced it with the relative source to the image file and it worked fine. I just don't wanna create a customized style for each button on the app. Any possible workaround?

like image 513
Waleed Avatar asked Dec 28 '11 13:12

Waleed


1 Answers

I have encountered this before, TemplateBinding does not work for custom dependency properties on controls. See these related questions:

issues with template binding and binding of custom component

TemplateBinding does not work in certain cases(when using TranslateTransform)

I have always used this instead:

{Binding MyProperty, RelativeSource={RelativeSource TemplatedParent}} 

It is semantically the same as TemplateBinding, and can also support value converters etc ...

like image 98
ColinE Avatar answered Sep 24 '22 07:09

ColinE