15

I want to create buttons with images and text inside. For example, i would use different images and text for buttons like 'Browse folders' and 'Import'.

One of the options would be to use a template. I had a look at similar question

Creating an image+text button with a control template?

But is there any way by which I can bind the source of image without using a dependency property or any other class?

halfer
  • 18,701
  • 13
  • 79
  • 158
Archie
  • 2,374
  • 8
  • 36
  • 50

7 Answers7

57

It doesn't have to be that complicated. Something as simple as putting a StackPanel inside a button will do the trick:

<Button>
  <StackPanel>
    <TextBlock>My text here</TextBlock>
    <Image Source="some.jpg" Stretch="None" />
  </StackPanel>
</Button>

Then you can configure the StackPanel to control where the text should appear, alignment, etc.

Marshal
  • 3,437
  • 1
  • 18
  • 14
  • Okay, but how do you set the underline character? If I put "_My text here" it renders the underline and alt+M no longer works. So how do you get that back? – BrainSlugs83 Dec 18 '13 at 02:28
  • Also, how do you get it to shrink the image so that the button doesn't explode to the size of your image (i.e. if I have an image that's 40x40 and a button of whatever size buttons are -- I don't want to manually set that -- how do I get the image to shrink to the right size instead of blow up my button to be uber large? – BrainSlugs83 Dec 18 '13 at 02:29
  • I'd like to add that you'll probably want to set the `Orientation` of the `StackPanel` to `Horizontal` to get them to line up side by side. Note that if you used a grid instead of a StackPanel you'd have to play with margins to center the image and text on the button horizontally (So the stackpanel is the way to go). – The Muffin Man Mar 06 '15 at 00:17
  • THIS is the answer – Khalil Khalaf May 11 '16 at 18:16
  • 1
    Now image and text are centered inside the button. How can I left-align them? – saidfagan Mar 29 '19 at 07:32
17

I added a few things to line them up nicely

<Button>
   <StackPanel Orientation="Horizontal">
       <Image Source="/ApplicationName;component/Images/MyImage.ico"/>
       <Label Padding="0">My Button Text</Label>
   </StackPanel>
</Button>
bensiu
  • 20,820
  • 48
  • 65
  • 104
Sean
  • 171
  • 1
  • 2
  • Well that worked to give me a normal button label (i.e. with alt+letter hot keys) -- I tested it clicks the button when I press the correct combination. -- Now I just need to figure out how to shrink my image to the size of the button and to not cause it to make the buttons all huge. – BrainSlugs83 Dec 18 '13 at 02:36
  • How can i stretch StackPanel inside the Button? `HorizontalAlignment="Stretch"` does not work. P.S. WPF is unpredictable and stupid. – saidfagan Mar 29 '19 at 07:30
7
    <Button>
        <StackPanel Orientation="Horizontal">
            <Image Source="Resources/add.png" Stretch="None" />
            <TextBlock Margin="5,0,0,0">Add</TextBlock>
        </StackPanel>
    </Button>
mpen
  • 237,624
  • 230
  • 766
  • 1,119
5
<Button x:Name="MyCoolButton"Width="200" Height="75">
<Grid >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Image Source="Pete-Brown-Silverlight-in-Action.png" Margin="5" Grid.Column="0" />
    <StackPanel Grid.Column="1" Margin="5">
        <TextBlock Text="Buy My Book!" FontWeight="Bold" />
        <TextBlock Text="Pete is writing THE Silverlight 4 book" TextWrapping="Wrap" />
    </StackPanel>
</Grid>

daniel
  • 375
  • 5
  • 6
2

No. What would you bind the Image.Source to? You need a DependencyProperty for this. Of course, you could also define a normal class which contains two properties: Text and ImageSource or Uri, and then use a DataTemplate to render instances of this class, but that would be even more code to write, and it is a little "smelly".

What is the reason you do not want to use a dependency property or a custom class?

gehho
  • 8,523
  • 2
  • 40
  • 55
  • The only reason is i wanted to know if there is any other simple way or you can say rather 'less-code' way to do it. With texblock i can use I wanted to know why cant i do the same with the Source property of an Image? – Archie Apr 28 '10 at 07:29
  • But **where** would you put that `TemplateBinding`? And to **which property** would you bind? – gehho Apr 28 '10 at 07:42
  • Can I use 'Tag' property to bind it? – Archie Apr 28 '10 at 07:45
  • I am not sure. It might work. However, personally, I would consider this as pretty bad code because the intention is not clear, you do not have any type-safety... It is up to you. – gehho Apr 28 '10 at 07:50
1

Added Stretch="Uniform" to Sean's answer to address case if the image is originally larger than the button size (issue BrainSlugs83 mentioned in his comments that I ran into as well). More details of Stretch options at MSDN.

<Button>
    <StackPanel Orientation="Horizontal">
        <Image Source="/ApplicationName;component/Images/MyImage.ico" Stretch="Uniform"/>
        <Label Padding="0">My Button Text</Label>
    </StackPanel>
</Button>

Wanted to add this as a comment to the answer under BrainSlugs83 but can't yet due to lack of points and was rejected from editing Sean's answer.

Michael Kohne
  • 11,516
  • 3
  • 43
  • 71
userN45290
  • 11
  • 2
0

For me the IconButton of the XCeed WPF Toolkit (freeware) does the trick.

marsh-wiggle
  • 1,693
  • 2
  • 23
  • 41