I am creating a WPF custom control, a Button
with an Image
and Text
. I have added two dependency properties to the control, ImagePath
and Text
, and the control template (in Themes\Generic.xaml) is a simple stack panel that arranges the image and text horizontally.
The Text
property works fine. But for some reason, the sample image in my test project doesn't appear when I use TemplateBinding
to the ImagePath
dependency property to get its path. I have tested the image by temporarily replacing the TemplateBinding
in the custom control with a path to the image, in which case it appears.
I am hoping that someone with more experience in this area can take a look and tell me why the control isn't working as expected. Thanks for your help.
My VS 2008 solution contains one project, CustomControlDemo. The project contains a custom control, TaskButton.cs, and a main window, Window1.xaml, that I use to test the control. My test image, calendar.png, is located in a Resources folder at the root level of the project, and Generic.xaml is located in a Themes folder, also at the root level of the project.
Here is the code for my custom control (from TaskButton.cs):
using System.Windows;
using System.Windows.Controls;
namespace CustomControlDemo
{
public class TaskButton : RadioButton
{
#region Fields
// Dependency property backing variables
public static readonly DependencyProperty ImagePathProperty;
public static readonly DependencyProperty TextProperty;
#endregion
#region Constructors
/// <summary>
/// Default constructor.
/// </summary>
static TaskButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(TaskButton), new FrameworkPropertyMetadata(typeof(TaskButton)));
// Initialize ImagePath dependency properties
ImagePathProperty = DependencyProperty.Register("ImagePath", typeof(string), typeof(TaskButton), new UIPropertyMetadata(null));
TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(TaskButton), new UIPropertyMetadata(null));
}
#endregion
#region Dependency Property Wrappers
/// <summary>
/// The ImagePath dependency property.
/// </summary>
public string ImagePath
{
get { return (string)GetValue(ImagePathProperty); }
set { SetValue(ImagePathProperty, value); }
}
/// <summary>
/// The Text dependency property.
/// </summary>
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
#endregion
}
}
And here is the control template (from Generic.xaml):
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CustomControlDemo">
<Style TargetType="{x:Type local:TaskButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:TaskButton}">
<StackPanel Height="Auto" Orientation="Horizontal">
<Image Source="{TemplateBinding ImagePath}" Width="24" Height="24" Stretch="Fill"/>
<TextBlock Text="{TemplateBinding Text}" HorizontalAlignment="Left" Foreground="{DynamicResource TaskButtonTextBrush}" FontWeight="Bold" Margin="5,0,0,0" VerticalAlignment="Center" FontSize="12" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
And finally, here is the Window1 markup that I am using to test the control:
<Window x:Class="CustomControlDemo.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:customControl="clr-namespace:CustomControlDemo"
Title="Window1" Height="300" Width="300">
<Grid>
<customControl:TaskButton ImagePath="Resources\calendar.png" Text="Calendar" />
</Grid>
</Window>
Any ideas why the image path isn't working? Thanks again.
Image doesn't take a string as a source :) You can see this in intellisense. You need to bind on an ImageSource (Or use an IValueConverter to convert the string to an ImageSource)
See this question for some tips on how to do this conversion.