How do I make a small image button with WPF - wpf

I'm trying to create a small (21 x 21) button that has an image on it. I want all of the normal behavior/effects of a normal button, except the image should take up most of the button's face.
I created the button:
<Button Grid.Column="2" Height="21" Width="21" HorizontalAlignment="Center" VerticalAlignment="Center">
<Image Source="{StaticResource CloseButton}"
Height="21" Width="21"
HorizontalAlignment="Center" VerticalAlignment="Center">
</Image>
</Button>
The image ends up squished, it looks like because of the default margin of the button?
I tried this answer which renders correctly, but then I lose the nice mouse-over effects and "click" look of the button.
The image itself is 21x21.
How can I get the effect I'm after?

Try This way, I am having the image and mouse over property in it.
<Button Width="25" Height="25">
<Image Width="21" Height="21" HorizontalAlignment="Center">
<Image.Source>
<BitmapImage UriSource="../images/icon.png"/>
</Image.Source>
</Image>
</Button>

In answer you attached target type of ControlTemplate is missing. It should be:
<ControlTemplate TargetType="{x:Type Button}">
...
</ControlTemplate>
It says your control template to have behavior of control you specify (in this case - Button)
Hope, it helps.

Related

WPF change button image from code behind

I would like to check which image is applied to the button and change it in code behind.
<Button x:Name="btnFlashAlert" Content="Button" Canvas.Left="87" Canvas.Top="258" Background="{x:Null}" Margin="136,244,409,215" BorderBrush="{x:Null}" BorderThickness="0" Cursor="Hand" Click="btnFlashAlert_Click">
<Button.Template>
<ControlTemplate>
<Image Source="Main/Images/FlashButton.png" Name="image"/>
</ControlTemplate>
</Button.Template>
</Button>
My goal is to make the button flash with different color button images not colors when certain values are met to inform the user they have certain types of messages waiting
You may bind the Source property to the Button's Content:
<Button x:Name="btnFlashAlert">
<Button.Template>
<ControlTemplate TargetType="Button">
<Image Source="{TemplateBinding Content}"/>
</ControlTemplate>
</Button.Template>
<Button.Content>
<BitmapImage UriSource="Main/Images/FlashButton.png"/>
</Button.Content>
</Button>
You may now set the Content to any other ImageSource in code:
btnFlashAlert.Content = new BitmapImage(new Uri(...));

WPF Changing text in a controltemplate at run time

I am making a template control so that I can have a button with an image that changes when you click it. I also am trying to get text on top of the button that can change at run time. I have the button images and everything working but I can't seem to get that label at runtime so I can change the text. Here is the code in the xaml. I am missing the code behind
<UserControl.Resources>
<ControlTemplate TargetType="{x:Type Button}" x:Key="ActionButton">
<Grid>
<Label Panel.ZIndex="2" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Arial" Name="lblText" Foreground="#5E4421" FontWeight="Bold" FontSize="14">Test</Label>
<Image Name="Normal" Source="/AssaultWare.Controls;component/Replayer/Images/button_off.png"/>
<Image Name="Pressed" Source="/AssaultWare.Controls;component/Replayer/Images/button_on.png"/>
<Image Name="Disabled" Source="/AssaultWare.Controls;component/Replayer/Images/button_off.png" Visibility="Hidden"/>
</Grid>
<ControlTemplate.Triggers>
...
</ControlTemplate.Triggers>
</ControlTemplate>
</UserControl.Resources>
<Button Canvas.Left="471" Canvas.Top="465" Template="{StaticResource ActionButton}" Name="btnRight"/>
Difficult to decipher your question, but I think you just need to change the Label to a ContentControl and bind its Content property to the Button's Content property:
<ContentControl Content="{TemplateBinding Content}" .../>

WPF Image Button formatting

If I create a button with an image inside, it gets blown up to much larger size than the image.
If i try to constrain the size of image, and container button, the image gets cut off:
<Button Background="Transparent" Width="18" Height="18" Margin="0,0,0,0" Padding="0,0,0,0" BorderBrush="{x:Null}">
<Image Width="16" Height="16" />
</Button>
Native image size is 16x16. Here the button is 18x18 with 0 padding, yet the image still gets cut-off on right/bottom.
how can i make the entire button be exactly the size of the image w/out any cut off?
The beauty (and curse?) of WPF is the ability to re-template controls.
You can set the template of the button something like the following (this is free hand, so you will need to tweak it a bit for your tastes):
<Button x:Name="btn16x16">
<Button.Template>
<ControlTemplate>
<Border HorizontalAlignment="Center" VerticalAlignment="Center" >
<Image Source="pack://siteoforigin:,,,/Resources/SixteenBySixteen.png"
Width="16"
Height="16"/>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
You should remove any Width and Height settings and set the Button's HorizontalAlignment and VerticalAlignment both to Center (or Left/Right or Top/Bottom resp.). By default, these properties are set to Stretch which makes the button stretch to the available space. Since the image is the content of the button, it also gets stretched. Something like this should work:
Take this code example:
<Button Background="Transparent" BorderBrush="{x:Null}" HorizontalAlignment="Center" VerticalAlignment="Center">
<Image Source="thePathToYourImage" Stretch="None"/> <!-- EDIT: added Stretch="None" here! -->
</Button>
.
The following was just meant as an alternative with a different result which obviously (considering your comments) is not what you want.
If you want the button to stretch, but not the image, you could also set the Image's alignment properties to something other than Stretch. Or you could set its Stretch property to None. This would make the button as large as possible, but keep the image at its original size (16x16). This would work as follows:
<Button Background="Transparent" BorderBrush="{x:Null}">
<Image Source="thePathToYourImage" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Button>
<!-- OR: -->
<Button Background="Transparent" BorderBrush="{x:Null}">
<Image Source="thePathToYourImage" Stretch="None"/>
</Button>
You can use Button.Background and ImageBrush as an exampe like this:
<Button Height="24" Width="24" >
<Button.Background>
<ImageBrush ImageSource="image name or path" Stretch="Fill" TileMode="None" />
</Button.Background>
</Button>
Think this might give people the answer they are looking for, buttons with image and no borders at all.

Get rid of button border in WPF?

i am trying to get rid of button border and only display text, however a thin line around the text gets displayed even though i set borderThickness to 0 and borderbrush to transparent.
my xaml code for save button:
<Button Content="save" Name="btnSaveEditedText"
Background="Transparent"
Foreground="White"
FontFamily="Tw Cen MT Condensed"
FontSize="30"
Margin="-280,0,0,10"
Width="60"
BorderBrush="Transparent"
BorderThickness="0"/>
Is there anyway i can get rid of the button border?
You need to override the ControlTemplate of the Button:
<Button Content="save" Name="btnSaveEditedText"
Background="Transparent"
Foreground="White"
FontFamily="Tw Cen MT Condensed"
FontSize="30"
Margin="-280,0,0,10"
Width="60"
BorderBrush="Transparent"
BorderThickness="0">
<Button.Template>
<ControlTemplate TargetType="Button">
<ContentPresenter Content="{TemplateBinding Content}"/>
</ControlTemplate>
</Button.Template>
</Button>
The method that I recently found to be most useful for this was to have your button use the style of a toolbars. This will only use the image or text while only showing button borders on mouse over.
<Button Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"
Content="save"
Name="btnSaveEditedText"
Background="Transparent"
Foreground="White"
FontFamily="Tw Cen MT Condensed"
FontSize="30"
Margin="-280,0,0,10"
Width="60"
BorderBrush="Transparent"
BorderThickness="0" />
You need to create a new Template for your buttons.
The easiest way to do this is open your project in Expression Blend, select the button and then right click and select "Edit Template > Edit a Copy..". This copies the existing template into one you can modify. It's easier if you create it in a resource dictionary.
Then select the template and on the Resource tab (on the right of the UI) select the ButtonFocusVisual. Select the Properties tab and expand the Miscellaneous section. This has BorderStyle and BorderThickness fields (among others). Set the style to None.
Templates will not solve this problem, your only course of action is to modify the WPF control. The solution is here:
How to remove ButtonChrome border (when defining the template of a border)?

WPF Rectangle does not have a Click event

It seems that the WPF Rectangle shape does not have the Click event defined. What am I supposed to use instead?
It does have MouseUp, but it's not quite the same behavior.
If you're not happy with MouseDown and MouseUp, perhaps you could just put the Rectangle in a Button and handle the Button's Click event?
<Button>
<Button.Template>
<ControlTemplate>
<Rectangle .../>
</ControlTemplate>
</Button.Template>
</Button>
It really depends with the behavior you're after. Please elaborate if needs be.
To add click handing to a Rectangle itself, you can use the InputBindings property:
<Rectangle Fill="Blue" Stroke="Black">
<Rectangle.InputBindings>
<MouseBinding Gesture="LeftClick" Command="{Binding FooCommand}"/>
</Rectangle.InputBindings>
</Rectangle>
This will cause the FooCommand to be executed when the rectangle is clicked. Handy if you're using MVVM!
I was looking for the related DoubleClick event and came across this suggestion to simply embed the object of interest in a ContentControl.
Here is their example (with a border, which also did not support click/double click).
<ContentControl MouseDoubleClick="OnDoubleClick">
<Border Margin="10" BorderBrush="Black" BorderThickness="2">
<Grid Margin="4">
<Rectangle Fill="Red" />
<TextBlock Text="Hello" FontSize="15" />
</Grid>
</Border>
</ContentControl>
Rectangle has event Tapped, which works fine. In designing universal apps for Windows 8.1, there are new events. Tapped, DoubleTaped, RightTapped and Holding.

Resources