How to keep image on Button to show on mouse-over? WPF - c#

I have a Button that I am adding an image via Window.Resources.
XAML for the Window.Resources
<Window.Resources>
<ImageBrush x:Key="MyResource" ImageSource="Pics\Button.png" />
</Window.Resources>
And the XAML for the Button,
<Button Name="Button1" Height="25" Grid.Column="0"
Grid.Row="0" Background="{StaticResource MyResource}" Click="Button1_OnClick" > stuff
</Button>
The problem I am getting is that the image disappears when you mouse-over the button. I tried quite a few things ,but I just can't stop this behavior. I still want the button to act as a normal button would on mouse-over with a color change to show that you are over it, but I have no idea how to go about this?
EDIT: The reasson I went with ImageBrush was so I could conform the image to the button.
EDIT 2: I need the image to change color like a normal mouse over would do.

Try this :
<Button Name="Button1" Height="25" Grid.Column="0"
Grid.Row="0" Click="Button1_OnClick">
<Border Background="{StaticResource MyResource}">
<TextBlock Text="stuff"/>
</Border>
</Button>

You could also set the Background based on MouseOver via the Button's ControlTemplate. This makes things much cleaner, as it's done all in xaml.
<Window.Resources>
<ImageBrush x:Key="MyResource" ImageSource="Pics\Button.png" />
<ImageBrush x:Key="MyResource2" ImageSource="Pics\Button2.png" />
<Style x:Key="MyButtonStyle" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Background" Value="{StaticResource MyResource}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border"
BorderThickness="0"
Background="Transparent">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource MyResource}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Background" Value="{StaticResource MyResource2}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Button Name="Button1"
Style="{StaticResource MyButtonStyle}"
Height="25"
Grid.Column="0"
Grid.Row="0"
Click="Button1_OnClick">stuff</Button>

OK, I figured this out,
I found this effective as it also shows you are over the button by reducing the opacity and this way only requires XAML, so it is much cleaner.
<Style x:Key="OpacityButton" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border" BorderThickness="1"
Padding="2,2,2,2" BorderBrush="#FFEE82EE"
Background="{TemplateBinding Background}"
CornerRadius="5">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="0.5" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This next way uses code behind the XAML and is not a clean as using just XAML ,but I am guessing there may be times when you might want to use code behind, so I am going to show this way as well.
<Style x:Key="TransparentStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="Transparent">
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then in the Button I added MouseEnter and MouseLeave events to change the image source,
<Button Name="Button1" Style="{StaticResource TransparentStyle}" Grid.Column="0" Grid.Row="0" Height="50" Width="70" Click="Button1_OnClick" MouseEnter="Button1_OnMouseEnter" MouseLeave="Button1_OnMouseLeave">
<StackPanel Orientation="Horizontal">
<Image x:Name="image4" Stretch="UniformToFill" />
</StackPanel>
</Button>
Then in the code behind,
private void Button1_OnMouseEnter(object sender, MouseEventArgs e)
{
string imageSource = #"c:\users\user\documents\visual studio 2015\Projects\TestAppForXAML\TestAppForXAML\Pics\1211794133.png";
image4.Source = new ImageSourceConverter().ConvertFromString(imageSource) as ImageSource;
}
private void Button1_OnMouseLeave(object sender, MouseEventArgs e)
{
string imageSource = #"c:\users\user\documents\visual studio 2015\Projects\TestAppForXAML\TestAppForXAML\Pics\1313321102.jpg";
image4.Source = new ImageSourceConverter().ConvertFromString(imageSource) as ImageSource;
}
This switches between two images when the mouse is enters or leaves ,giving you the effect that a normal mouse over gives you.

Related

C# WPF Change Button Color Resource On RunTime

I have a button that i want to have a dynamic color based on if a file exists.
I am using two resources to do this, one resource is a color and one is a SolidColorBrush. They are declared as so
<Window.Resources>
<Color x:Key="ColorName">Red</Color>
<SolidColorBrush x:Key="ButtonColor1" Color="{StaticResource ColorName}" />
</Window.Resources>
Now, my button is done in a strange way as i wanted to change the highlight color, its done as so
Button Grid.Row="1" Grid.Column="2" Height="25" Width="25"
HorizontalAlignment="Center" VerticalAlignment="Center" Click="Button_Click"
Name="SalutButton">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="{StaticResource
ButtonColor1}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="Black" BorderThickness="1">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="LightGreen"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
My code to try and change the resource is:
Resources["ColorName"] = System.Windows.Media.Colors.Green;
This successfully changes the resource colorname, but the buttoncolor1 resource is already made during initialisation and takes the default color of colorname which is red, so even though im changing the resource its not updating.
Any ideas?

WPF Rounded border button responsive to click color change

I have a button on my WPF application (MVVM Pattern) which is responsive to a click event. Basically if you click on this button its background becomes LightGreen (the default color is LightGray). I already achieved the desired behavior using the following code:
<Button Grid.Column="2" Grid.Row="6" Grid.ColumnSpan="3" Grid.RowSpan="2" Content="{Binding FirstSchedule.Message}" Command="{Binding FirstScheduleButtonClick}">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="LightGray"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding FirstScheduleButtonSelected}" Value="True">
<Setter Property="Background" Value="LightGreen"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
In which FirstScheduleButtonSelected is a ViewModel property defined by:
private bool _firstScheduleButtonSelected;
public bool FirstScheduleButtonSelected
{
get { return _firstScheduleButtonSelected; }
set { _firstScheduleButtonSelected = value; NotifyPropertyChanged("FirstScheduleButtonSelected"); NotifyPropertyChanged("Background"); }
}
Now I need to make this button's borders rounded. I already tried this solution How to create/make rounded corner buttons in WPF?, and I ended up with:
<Button Grid.Column="2" Grid.Row="6" Grid.ColumnSpan="3" Grid.RowSpan="2" Content="{Binding FirstSchedule.Message}" Command="{Binding FirstScheduleButtonClick}">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border CornerRadius="15" Background="LightGray" BorderThickness="1" Padding="2">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="LightGray"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding FirstScheduleButtonSelected}" Value="True">
<Setter Property="Background" Value="LightGreen"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Now my borders are, in fact, rounded but when I click the button it does not becomes green.
Q: How can I modify this button in order to make its borders rounded and keep my already functioning behavior of changing its color on click?
Here's what I'd do:
<Window.Resources>
<!-- ... -->
<Style x:Key="GreenToggleButtonStyle" TargetType="ToggleButton">
<Setter Property="Background" Value="LightGray" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border
CornerRadius="15"
Background="{TemplateBinding Background}"
BorderThickness="1"
Padding="2"
>
<ContentPresenter
HorizontalAlignment="Center"
VerticalAlignment="Center"
/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter
Property="Background"
Value="LightGreen"
/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- ... -->
</Window.Resources>
...
<ToggleButton
Grid.Column="2"
Grid.Row="6"
Grid.ColumnSpan="3"
Grid.RowSpan="2"
Content="{Binding FirstSchedule.Message}"
IsChecked="{Binding FirstScheduleButtonSelected}"
Style="{StaticResource GreenToggleButtonStyle}"
/>

WPF issue with button background image

I have my wpf button as follows
<Button x:Name="helpButton" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="552,201,95,726" Width="32" Height="32" BorderThickness="0" Click="helpButton_Click">
<Button.Background>
<ImageBrush ImageSource="/Images/help-icon1.png"></ImageBrush>
</Button.Background>
</Button>
On window load I am able to see the image perfectly but when I hover the mouse I am not able to see the image
So can some one help me
A more sensible approach to start would be by using <Button.Template> instead of <Button.Background>
<Button x:Name="helpButton">
<Button.Template>
<ControlTemplate>
<Border HorizontalAlignment="Center" VerticalAlignment="Center" >
<Image Source="/Images/help-icon1.png" Width="32" Height="32"/>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
Additionally style the button border with for example a hover effect with Trigger and Setter
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="buttonBorder" Property="BorderBrush" Value="Green"></Setter>
<Setter TargetName="buttonBorder" Property="BorderThickness" Value="1" />
</Trigger>
</ControlTemplate.Triggers>
which you will add like so:
<Button x:Name="helpButton" Height="35">
<Button.Template>
<ControlTemplate>
<Border Name="buttonBorder" HorizontalAlignment="Center" VerticalAlignment="Center" >
<Image Source="/Images/help-icon1.png" Width="32" Height="32"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="buttonBorder" Property="BorderBrush" Value="Green"/>
<Setter TargetName="buttonBorder" Property="BorderThickness" Value="1"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
It is really strange why it is not possible to see image when button is hovered. Default style always shows Content(in your case, image). So I suggest you just use default style for your button:
<Button Style="{ x:Null}">
<Image Source="/images/images.jpg"></Image>
</Button>
Or just override behavior of template when mouse is over button:
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="Black" BorderThickness="1">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<!--Do not do any actions here to see your image-->
</Trigger>
</Style.Triggers>
</Style>
In this case, there is no actions when mouse is over your button.

Texbox with button in it

How can I create an TextBox in WPF ( With XAML ) that there is an button inside it, Just like Google Chrome Adressbar.
I want somethings like the picture below :
And then how can I change the position of the button to the right and left ? ( I'm using C# )
You could nest the button inside a Grid on top of the TextBox, since it sounds like you only need to use this once:
e.g.
<Grid>
<TextBox Text="Hello" />
<Button HorizontalAlignment="Right" Content="Click Me" />
</Grid>
The only issue with this is that the text will show under the button. An alternative is to make your own usercontrol or to edit the controltemplate of the textbox (but this will probably not have the functionality you want).
I'd create a textbox in the left column of a 2 column grid, then the button in the right column. Then remove the background and border on the textbox and put this background/border on the grid. This will give the appearance of a textbox with a button in where the text can't go underneath the button
e.g.
<Border BorderBrush="LightGray" BorderThickness="1" Height="30">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBox VerticalAlignment="Center" BorderBrush="Transparent" Background="Transparent" Text="Hello World this is a really long bit of text that wont go underneath the button (it will get clipped)"></TextBox>
<Button Content="Click me" Grid.Column="1" Margin="4"></Button>
</Grid>
</Border>
Only problem you have with that is that you don't get the chrome hover effect etc etc. Usercontrol with control template is your best option, but this gives you some ideas
The way to do this :
<Border x:Name="TextboxBorder" BorderBrush="#FFB8AAAA" BorderThickness="1" Grid.Column="2" Margin="3,1.5,4.084,1.5" Height="27" Background="White" CornerRadius="3">
<Grid x:Name="TextboxGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="33"/>
</Grid.ColumnDefinitions>
<Button x:Name="btn" Grid.Column="1" Margin="3.5,4.833,4.5,3.5" BorderBrush="{x:Null}" Style=" {DynamicResource SearchButtonStyle}" >
<Button.Background>
<ImageBrush ImageSource="Images/search.png"/>
</Button.Background>
</Button>
<TextBox Padding="0,1.2,0,0" x:Name="txt" Margin="1.541,0.5,2.041,0.5" TextWrapping="Wrap" Text="سلام" BorderThickness="0" FontSize="16"/>
</Grid>
</Border>
And the Button style is :
<Style x:Key="SearchButtonStyle" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderThickness="0" Margin="1.875,0.5,1.75,-0.375" Background="{TemplateBinding Background}" Width="16" Height="16"/>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true"/>
<Trigger Property="ToggleButton.IsChecked" Value="true"/>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And Then WPF Rocks!!!

How do I change the entire style of a button from code behind in realtime?

I have a button that flashes.
I would like to change the entire button style from a resource dictionary when ever it flashes.
I would think it would be like this:
DesktopWindow.AlertButton.Style = (Style)DesktopWindow.Resources["GreenAlertButtonStyle"];
But that doesn't work. How do I do this? I cannot simply change the background color (although that's all I really want to do) because I want to preserve the triggers. When ever I change the background of the button right now, the mouseover triggers stop working....
The button:
<Style TargetType="Button" x:Key="BaseAlertButtonStyle">
<Setter Property="ToolTip" Value="Show Alert List"/>
<Setter Property="Effect" Value="{DynamicResource dropShadow}" />
<Setter Property="Background" Value="{DynamicResource AlertButtonBackground}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Border CornerRadius="5" x:Name="ButtonBorder" Margin="0,0,0,0"
VerticalAlignment="Stretch" BorderThickness="0"
BorderBrush="#ffffff" Padding="0"
Background="{TemplateBinding Background}"
HorizontalAlignment="Stretch">
<Image x:Name="alertImage">
<Image.Source>
<BitmapImage UriSource="/resources/alertIcon.png" />
</Image.Source>
</Image>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="{DynamicResource ButtonRolloverBackground}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I dont wanna hear it about doing a search for this issue....
Try:
DesktopWindow.AlertButton.Style = FindResource("GreenAlertButtonStyle") as Style;
After setting background explicitly you have to clear BackgroundProperty and then set new style.
button1.ClearValue(BackgroundProperty);

Categories

Resources