I'm pretty sure it would be cleaner to go through the "Template" property and use a ControlTemplate and TemplateBindings, but that would mean re-creating the border and other stuff around your content, so if you are looking to just define a default "Content", my example would be the way to go, I think.

I like this answer much better, too. I don't usually think to do attached properties, but they're an awesome feature of WPF.
–
dustyburwellMar 16 '09 at 17:44

Indeed they are. The fact that you can attach behavior to elements through attached properties (like declarative handling of events for things like Drag and Drop) is even more awesome when you get to it.
–
Denis TrollerMar 16 '09 at 17:52

I've got one question though: Is there any reasone to use DynamicResource? Wouldn't StaticResource be sufficient?
–
surfenMar 27 '12 at 22:35

This worked for me after I made a slight change to the style markup. I had to remove the "Path=" from both the Image and TextBlock Binding due to a path exception. Now my Image element looks like: <Image Source="{Binding (local:ImageButton.Image), RelativeSource={RelativeSource AncestorType={x:Type Button}}}" /> Hope it helps.
–
GarryJun 16 '12 at 14:14

If the only added functionality that you want for your button is to have an image on it, then I think you're approaching this from the wrong direction. WPF is as awesome as it is because the UI controls are look-less. This means that a Control is merely a definition of functionality + some template to define how it looks. This means that the template can be swapped out at any time to change the look. Also, almost any content can be placed inside of almost any control

For instance, to define a button in your xaml that has the look your going for all you need is this:

Just keep in mind that with WPF you don't have to define a new CustomControl or UserControl every time you want to change the look and feel of something. The only time you should need a CustomControl is if you want to add functionality to an existing Control or to create functionality that doesn't exist in any other Control.

Edit Due to comment:

If you're wanting to keep from defining the content for the button every time, the other option is to just have a poco (plain old CLR object) class that would define everything your interested in (I'll write my example as if you're doing this for a tool bar, because it makes sense to me):

I just don't know that the way you're trying to do it is the most WPF way you could do it.

EDIT Updated based on second comment
Sorry, I forgot to include the ContentControl surrounding that. Now that I remembered that, I realize that that's not much less verbose than the original where you are specifying the content manually. I'll post a new answer to help with your original question.

Hi, I know this. Actually the goal of creating a user control was to avoid writing this for all the buttons. Doing this, I only had to write: <uc:ImageButton ButtonCommand="{Binding AttachContextCommand}" ButtonImage="{StaticResource AssociateImage}" /> It's just refactoring if you want.
–
RoubachofMar 15 '09 at 0:40

Sorry but this isn't working... ToolBarItem is not an UIElement and when I try to launch the app, I get an exception that tells me so.
–
RoubachofMar 16 '09 at 9:49

What I think you want to do is create a new CustomControl called ImageButton. Then change it to extend from Button instead of Control. You won't need a Command property since Button already has one. You'll only need to add an Image property and you can reuse the Content property from button instead of having a Text property.

When your CustomControl is created, it'll add an entry in your Generic.xaml for the default style of your ImageButton. In the Setter for the Template property you can change the ControlTemplate to this:

The built-in WPF button contains code that fires the attached command in response to being clicked. Your "ImageButton" derives from UserControl, so you don't get that behavior. Probably the shortest route to get what you want is for your ImageButton class to actually derive from the WPF Button class. To accomplish that, change the markup for ImageButton from

<UserControl
...
>
...
</UserControl>

to

<Button
...
>
...
</Button>

Then change the base class of ImageButton from UserControl to Button.

You'll probably need to make some other minor changes before it all works.