I'm trying to create a flat styled wpf button. Like on the picture below (the log-out button). I want to have an image and text inside the button even if you hover it. But what happened is every time i try to put a hover style/effects the button turn plain blue when hover and image and text are missing.
Can anyone help me with this? Thank you!
Here's what I tried so far :
<Button Name="button_lgout">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}"></ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
<Image Source="Images/logout.png" Height="21" VerticalAlignment="Top" Margin="0,5,0,0"/>
<Label Name="lbl_lgout" Content="LOGOUT" FontSize="12" Foreground="White" FontFamily="Calibri" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="0,0,0,-4" Height="27" />
I think some of your code is missing, from the question. eg. the Control template does not have any visual tree. also seems like you are also talking about some triggers, mouse hover etc. please include them too if necessary
however to create a plain button with any arbitrary content you may use this example
<Button Name="button_lgout">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<ContentPresenter TextElement.Foreground="{TemplateBinding Foreground}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
<StackPanel>
<Image Source="Images/logout.png" Height="21" HorizontalAlignment="Center" Margin="0,5,0,0"/>
<Label Name="lbl_lgout" Content="LOGOUT" FontSize="12" Foreground="White" FontFamily="Calibri" HorizontalAlignment="Center" Height="27" />
</StackPanel>
</Button>
you may also try to set <StackPanel HorizontalContentAlignment="Center"> and see if this can replace HorizontalAlignment="Center" from sub items. also Foreground="White" is redundant as specified in the button style, you may safely remove either of them
Enable hover effect
as requested here is how you can implement a simple hover effect. assuming that the container of the button has the desired color, this effect will darken the background color
<Button Name="button_lgout" HorizontalAlignment="Center" VerticalAlignment="Top">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background"
Value="Transparent" />
<Setter Property="Foreground"
Value="White" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter TextElement.Foreground="{TemplateBinding Foreground}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="true">
<Setter Property="Background"
Value="#2000" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
<StackPanel>
<Image Source="desert.jpg"
Height="21"
HorizontalAlignment="Center"
Margin="0,5,0,0" />
<Label Name="lbl_lgout"
Content="LOGOUT"
FontSize="12"
Foreground="White"
FontFamily="Calibri"
HorizontalAlignment="Center"
Height="27" />
</StackPanel>
</Button>
I have added <Setter Property="Background" Value="Transparent" />. this is necessary for TemplateBinding to work with the setters in triggers, these setter can also be used with TargetName but former approach will also help to define a base color if needed. I also added a control template trigger for IsMouseOver to apply the effect
if you want to increase the darkness, increase the alpha component 2 in Value="#2000". possible hex values are 0 to F where is 0 is least dark and F is most dark
You need to add ContentPresenter in button template and move the image and label inside some panel and add them as child of button:
<Button Name="button_lgout">
<Button.Template>
<ControlTemplate TargetType="Button">
<ContentPresenter/>
</ControlTemplate>
</Button.Template>
<Grid>
<Image Source="Images/logout.png" Height="21" VerticalAlignment="Top"
Margin="0,5,0,0"/>
<Label Name="lbl_lgout" Content="LOGOUT" FontSize="12" Foreground="White"
FontFamily="Calibri" VerticalAlignment="Bottom"
HorizontalAlignment="Center" Margin="0,0,0,-4" Height="27" />
</Grid>
</Button>
Related
I wonder if there is a way to do it for all the future buttons and other controls or do i need to make a solution for each control/button ? And how to do it ?
I want to disable the mouse hove highlight.
<Button x:Name="btnTest" Content="Start Watching" HorizontalAlignment="Left" Margin="14,241,0,0" VerticalAlignment="Top" Width="109" RenderTransformOrigin="0.484,-0.066" Height="30" FontSize="16" Background="#FFFB0000" Click="btnTest_Click"/>
<TextBox HorizontalAlignment="Left" Height="30" Margin="14,175,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="644"/>
<Button Content="Browse" Margin="673,175,18,0" VerticalAlignment="Top" RenderTransformOrigin="-0.111,0.769" Height="30" FontSize="16"/>
Add it to your ResourceDictionary:
<Style TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border"
BorderThickness="1"
Padding="4,2"
BorderBrush="DarkGray"
CornerRadius="3"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And since Style has no key it will be on all the buttons
You'll need to create a style. if you want it to be applied through your whole app, you'll need to put it into your "app.xaml" file (within an application.Resources).
Bellow is an example of how to do it. I added some stuff like setters to illustrate that you can add properties, you could also add triggers and many things.
Not setting a "x:key" to your style will make them the default one (thus overriding the basic one), as the one below, if you wish to have a collection of styles, give them keys.
`<Style TargetType="{x:Type Button}">
<Setter Property="Background"
Value="Transparent" />
<Setter Property="BorderThickness"
Value="0" />
<Setter Property="Cursor"
Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center">
</ContentPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>`
I have a button with the following properties:
<Grid Margin="0,0,593,0">
<Button x:Name="btnToolbarClose" Content="X" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" Grid.Column="1" HorizontalAlignment="Right" VerticalAlignment="Top" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" FontSize="12" FontFamily="Arial" Height="23" Width="30" Margin="0,-1,-1,0"/>
<Button x:Name="btnToolbarMax" Content="£" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" Grid.Column="1" HorizontalAlignment="Right" Margin="0,-1,29,0" VerticalAlignment="Top" FontFamily="Wingdings 2" VerticalContentAlignment="Center" FontSize="12" Height="23" Width="30" />
<Button x:Name="btnToolbarMin" Content="─" Grid.Column="1" HorizontalAlignment="Right" Margin="0,-1,59,0" VerticalAlignment="Top" VerticalContentAlignment="Bottom" HorizontalContentAlignment="Center" FontSize="14" Height="23" Width="30" >
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="{x:Null}"/>
<Setter Property="BorderBrush" Value="{x:Null}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="Black" BorderThickness="0">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Grid>
And now I want that I don't have to insert this button style for each button, but simply use this style for the other buttons with bindings?So that I only have to write this style once and use it for the other buttons?
An easy way to reuse styles of WPF controls is by using ResourceDictionaries.
Link to MSDN
After adding a ResourceDictionary to your project, you can reference it by adding it to the start of your XAML like this:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="./YourNewDictionary.xaml"/> // This points to the location of your dictionary.
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
You can define your custom style in your newly added ResourceDictionary somewhat like this:
<Style x:Key="YourButtonStyle" TargetType="Button">
<Setter Property="Margin" Value="5"/>
And all other customized properties....
</Style>
You can then reference your custom style in your control like this:
<Button x:Name="YourButton" Style="{StaticResource YourButtonStyle}">
This lets you easily create custom styles wich you can reuse throughout your project without much clutter in your XAML files.
I tried many different options to change the backgroundcolor on hover, but it dosen't work for me.
Here is my code:
<Button x:Name="bAction" HorizontalAlignment="Center" Margin="0,500,0,0" VerticalAlignment="Center" Height="100" Width="1000" BorderBrush="Black" OpacityMask="White" Background="#FF5B5B5B" IsDefault="True" Click="bAction_Click">
<TextBlock x:Name="tbAction" TextWrapping="Wrap" Text="Test" Foreground="White" IsEnabled="False" Width="990" Height="85" FontFamily="Letter Gothic Std" FontSize="21.333" FontWeight="Bold" TextDecorations="{x:Null}" TextAlignment="Center"/>
</Button>
Try applying the below style to Button
<Style x:Key="myStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Background"
Value="Red" />
</Trigger>
</ControlTemplate.Triggers>
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I am using Blend for visual Studio 2012 and I have a problem, I need to change the image from a resource to three buttons
I convert an image to button
these resource is for one button:
<Window.Resources>
<Style x:Key="AppBtn" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Image x:Name="image" Source="1394235016_close.png" Stretch="None" Opacity="0.8" />
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" TargetName="image" Value="1"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Button Style="{DynamicResource AppBtn}" Click="Button_Click" Margin="2,0,2,0" />
for one button is ok but I need to aply this resource to another two button but I need to change the image tag (for change the image)
how I do this?
I tested this and it worked
in your style do the following
<Image x:Name="image" Source="{Binding RelativeSource={RelativeSource TemplatedParent},
Path=Tag}" Stretch="None" Opacity="0.8" />
and in your button
<Button x:Name="Search_Button" Click="Button_Click"
Style="{DynamicResource AppBtn}" Tag="your resource"/>
Change the tag in each button to give your image resource
Try this
In the style template
<Image x:Name="image" Source="{TemplateBinding ImageSource}" Stretch="None" Opacity="0.8" />
and when you apply the button on page try following;
<local:AppBtn ImageSource="*yoursource*" />
<Button Style="{DynamicResource AppBtn}" Click="Button_Click" Margin="2,0,2,0" />
repeat for each button with different image source
Not sure it will work, but you can try
I have two button with the code in xaml is:
<Button Grid.Row="0" Grid.Column="2" Style="{StaticResource styleInfomationButton}" />
<Button Grid.Row="1" Grid.Column="2" Style="{StaticResource styleInfomationButton}" />
They're same style, but in runtime they were presented differently:
Here the image how the form showed:
Style applied:
<Style x:Key="styleInfomationButton" TargetType="Button">
<Setter Property="Width" Value="22" />
<Setter Property="Height" Value="22" />
<Setter Property="Content">
<Setter.Value>
<TextBlock FontWeight="ExtraBold" Foreground="White">?</TextBlock>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Width="20" Height="20">
<Ellipse Fill="#81A9F0" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
When I tried the above code, it failed at runtime with the error:
Specified element is already the logical child of another element. Disconnect it first
Then, I looked at the code again and see you are setting Content property in the style. When you tried to apply the Style to two buttons, WPF tries to set the same TextBlock element as Content for the two buttons - this can't work. In WPF, for any element, you can only have one logical parent.
Update your style to the following, to get the desired behavior:
<Style x:Key="styleInfomationButton" TargetType="{x:Type Button}">
<Setter Property="Width" Value="22" />
<Setter Property="Height" Value="22" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid Width="20" Height="20">
<Ellipse Fill="#81A9F0" />
<<TextBlock FontWeight="ExtraBold" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center">?</TextBlock>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Very good article on Understanding the Visual Tree and Logical Tree in WPF