WPF Button Binding String Instead Of Imagesource With Dependency Property


Here, we are going to see a way to reuse the dependency property created for binding in a WPF button. It is not always necessary to create multiple dependency properties with the different return types. The below steps show how to reuse the same dependency property for string as well as ImageSource type and this can be applied wherever similar scenario is applicable.

Step 1 - Creating a dependency property

Create dependency property with only string type which we are going to reuse for string and ImageSource type. The commented one in the code is for ImageSource type whose functionality is achieved with string type itself.

  1. public class MyButton :Button  
  2.     {  
  3.         public static readonly DependencyProperty MyContentProperty =  
  4. DependencyProperty.Register("MyContent"typeof(string), typeof(MyButton));  
  5.         public string MyContent  
  6.         {  
  7.             get  
  8.             {  
  9.                 return (string)GetValue(MyContentProperty);  
  10.             }  
  11.             set  
  12.             {  
  13.                 SetValue(MyContentProperty, value);  
  14.             }  
  15.         }  
  16.     //below code is for ImageSource type which is achieved with above string type  
  17.         //        public static readonly DependencyProperty MyImageSourceProperty =  
  18.         //DependencyProperty.Register("MyImageSource", typeof(ImageSource), typeof(MyButton));  
  20.         //        public ImageSource MyImageSource  
  21.         //        {  
  22.         //            get { return (ImageSource)GetValue(MyImageSourceProperty); }  
  23.         //            set { SetValue(MyImageSourceProperty, value); }  
  24.         //        }  
  25.     }  

Step 2 - Creating style for custom button

Create either ‘application-wide’ or ‘window-wide’ style to create a custom button. Styles can be in any form and are based on the application requirement. Below styles are created for demo which can be modified further.

  1. <!--Style for button with text and image-->  
  2. <Style x:Key="DemoButton1"  TargetType="{x:Type btn:MyButton}">  
  3.         <Setter Property="Template">  
  4.             <Setter.Value>  
  5.                 <ControlTemplate TargetType="{x:Type btn:MyButton}">  
  6.                     <Border Background="{TemplateBinding Background}">  
  7.                         <WrapPanel>  
  8.                             <TextBlock Text="{TemplateBinding Content}"  Foreground="White" FontSize="15" ></TextBlock>  
  9.                             <Image Source="{Binding MyContent,RelativeSource={RelativeSource TemplatedParent}}" />  
  10.                         </WrapPanel>  
  11.                     </Border>  
  12.                 </ControlTemplate>  
  13.             </Setter.Value>  
  14.         </Setter>  
  15.     </Style>  
  17. <!--Style for button with repeated text i.e same text repeated twice in stack form inside button-->  
  18.     <Style x:Key="DemoButton2"  TargetType="{x:Type btn:MyButton}">  
  19.         <Setter Property="Template">  
  20.             <Setter.Value>  
  21.                 <ControlTemplate TargetType="{x:Type btn:MyButton}">  
  22.                     <Border Background="{TemplateBinding Background}">  
  23.                         <StackPanel>  
  24.                             <TextBlock></TextBlock>  
  25.                             <TextBlock Text="{TemplateBinding MyContent}"  Foreground="White" HorizontalAlignment="Center" FontSize="15"></TextBlock>  
  26.                             <TextBlock Text="{TemplateBinding MyContent}"  Foreground="White" HorizontalAlignment="Center" FontSize="15"></TextBlock>  
  27.                         </StackPanel>  
  28.                     </Border>  
  29.                 </ControlTemplate>  
  30.             </Setter.Value>  
  31.         </Setter>  
  32.     </Style>  

Include the namespace in <ResourceDictionary> in case of application-wide style or in <Window> in case of window-wide style like below.

  1. xmlns:btn="clr-namespace:MyWpfApplication.CustomButton"   

In the above namespace,

  • MyWPFApplication – project name
  • CustomButton – Folder containing class for dependency property

Step 3 - Creating custom button

Include the namespace in the window as given in the above example and start creating the custom button.

  1. <!--custom button with DemoButton1 style-->  
  2.         <btn:MyButton Style="{StaticResource DemoButton1}" Content= "Home button with image" MyContent="pack://application:,,,/Images/home.png" Background= "#FFE87B3E" Grid.Column="1" Grid.Row="1"></btn:MyButton>  
  4. <!--custom button with DemoButton2 style-->  
  5.         <btn:MyButton Style="{StaticResource DemoButton2}" MyContent="Click!!" Background="#FF27AF3E" Grid.Column="3" Grid.Row="1"></btn:MyButton>  

Mention the image path in form of pack URI only.

Output screenshot



Thus, by using the one property, we are able to make it fit for multiple purposes. With the help of the example discussed many scenarios can be created. Start using and enjoy!!