Convert image to button - wpf

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

Related

How can I use a button style as a template for the other buttons?

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.

WPF - Change backgroundcolor on button hover

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>

WPF Flat button style with image and text inside even when hover

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>

How to Clear Triggered Control Template

I am trying to achieve the "hint text" functionality for a TextBox in WPF. I can set the default text fine, but the problem comes when I want the control to return its appearance to a normal TextBox. Here is the trigger I have so far:
Trigger A
<Trigger Property="Text" Value="{x:Static sys:String.Empty}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<TextBox>
<TextBox.Background>
<VisualBrush AlignmentX="Left" AlignmentY="Center" Stretch="UniformToFill">
<VisualBrush.Visual>
<Label Content="{TemplateBinding TextBox.Tag}" Background="White"/>
</VisualBrush.Visual>
</VisualBrush>
</TextBox.Background>
</TextBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
This sets the Background to a VisualBrush when the Text property is empty. What I need to do is clear this ControlTemplate when the user selects the TextBox to input text.
Here is what I tried:
Trigger B
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<TextBox/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
These two don't work together. I tested each by changing the Background colors. If I comment out either one, they will each work. If both are uncommented, Trigger A works and B is never seen. How can I remove/overwrite Trigger A?
I know that the functionality of these templates is supposed to clear when the trigger condition is no longer met, but for example, Trigger A's setting will not go away when I enter text into the TextBox like it should. Like the Text property is still String.Empty or something.
So what am I missing?
EDIT:
Here is the whole style (there's not much more to it):
<UserControl.Resources>
<Style TargetType="TextBox" x:Key="FormsTextBox">
<Setter Property="Width" Value="45"/>
<Setter Property="Margin" Value="3 2 3 2"/>
<Style.Triggers>
<Trigger Property="Text" Value="{x:Static sys:String.Empty}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<TextBox>
<TextBox.Background>
<VisualBrush AlignmentX="Left" AlignmentY="Center" Stretch="UniformToFill">
<VisualBrush.Visual>
<Label Content="{TemplateBinding TextBox.Tag}" Background="White" Width="45"/>
</VisualBrush.Visual>
</VisualBrush>
</TextBox.Background>
</TextBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
I cannot see whole template but this looks a bit overcomplicated. I assume you're trying to achieve watermark text. For hint use box standard ToolTip property, which by default will display your text in a popup when hover your TextBox but this behaviour can be disabled and ToolTip property reused. You can either create reusable Style - which I prefer - for TextBox, something like this:
<Window ...>
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<Style TargetType="{x:Type TextBox}" x:Key="WatermarkTextBoxStyle">
<Setter Property="ToolTipService.IsEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
BorderThickness="1"
BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}">
<Grid>
<TextBlock Margin="5,0,0,0"
Text="{TemplateBinding ToolTip}"
Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Text.IsEmpty, Converter={StaticResource BooleanToVisibilityConverter}}"
Opacity="0.5"/>
<ScrollViewer Name="PART_ContentHost"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<TextBox ToolTip="watermark text" Style="{StaticResource WatermarkTextBoxStyle}"/>
</Window>
or, if it's a one-off thing, then do you can do something like this without any Style or Template:
<Grid Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">
<TextBlock Margin="5,0,0,0"
Text="watermark text"
Opacity="0.5"
Visibility="{Binding ElementName=myTextBox, Path=Text.IsEmpty, Converter={StaticResource BooleanToVisibilityConverter}}" />
<TextBox Name="myTextBox" Background="Transparent" />
</Grid>

Customizing Context Menu in WPF

I have a project here where I require customizing the context menu in my WPF application in which a button would be placed at the bottom of all the menuitems.
However, if I were to add the button through the XAML, it would appear as another item in the collection in the context menu and the mouse-over highlight would act on it.
I would like to have the context menu tuned to a grid-like style whereby I could customize the style underneath it.
Any idea how I can achieve this (preferably in the XAML)?
It's actually pretty straightforward in the XAML.
Just define it under the element for which you want to have the context menu.
<Border>
<Border.ContextMenu>
<ContextMenu>
<ContextMenu.Template>
<ControlTemplate>
<Grid>
<!--Put anything you want in here.-->
</Grid>
</ControlTemplate>
</ContextMenu.Template>
</ContextMenu>
</Border.ContextMenu>
</Border>
For your menu item style with the button in the item you can use the following code:
Note - Adding items to the Header will keep it in the same MenuItem, but if added to the MenuItem only it will be regarded as a new MenuItem.
<ContextMenu>
<ContextMenu.Items>
<MenuItem>
<MenuItem.Header>
<StackPanel>
<TextBlock Text="Item 1"/>
<Button Content="Button 1" Margin="5"/>
</StackPanel>
</MenuItem.Header>
</MenuItem>
<MenuItem>
<MenuItem.Header>
<StackPanel>
<TextBlock Text="Item 2"/>
<Button Content="Button 2" Margin="5"/>
</StackPanel>
</MenuItem.Header>
</MenuItem>
</ContextMenu.Items>
</ContextMenu>
This will be the resulting ContextMenu:
From there you can style the MenuItem or Button etc.
Hope it helps!
You can start with the example style/template (from here) for ContextMenu and adjust it to your needs.
<Style TargetType="{x:Type ContextMenu}">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Grid.IsSharedSizeScope" Value="true" />
<Setter Property="HasDropShadow" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContextMenu}">
<Border x:Name="Border"
Background="{StaticResource MenuPopupBrush}"
BorderThickness="1">
<Border.BorderBrush>
<SolidColorBrush Color="{StaticResource BorderMediumColor}" />
</Border.BorderBrush>
<StackPanel IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Cycle" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="HasDropShadow" Value="true">
<Setter TargetName="Border" Property="Padding" Value="0,3,0,3" />
<Setter TargetName="Border" Property="CornerRadius" Value="4" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Resources