first of all I apologize for my English.
I am making a simple C# WPF app. I've added an ellipse,label1,label2 onto my MainWindow.xaml.
I want to make these 3 objects (ellipse,label1,label2) into a button. I want this button to load my second wpf page, called "Size". As I understand it should be an area button. I've tried to use "border" (from WPF controls) with "MouseDown" (from event handler) but the effect is not that good. Any tips? What should I do?
The code I've used for event handler is:
private void Border_MouseDown(object sender, MouseButtonEventArgs e)
{
Size secondPage = new Size();
secondPage.Show();
this.Close();
}
You need to redefine button style, You can do it using ControlTemplate. Here is example how to write reusable style that redefines button.
I have added also an example how to implement color change on IsPressed event.
<Window x:Class="ColorTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary>
<LinearGradientBrush x:Key="ButtonBackground" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#FFD9EDFF" Offset="0"/>
<GradientStop Color="#FFC0DEFF" Offset="0.445"/>
<GradientStop Color="#FFAFD1F8" Offset="0.53"/>
</LinearGradientBrush>
<Style x:Key="SimpleButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Border Background="{StaticResource ButtonBackground}" VerticalAlignment="Stretch" CornerRadius="2" HorizontalAlignment="Stretch"/>
<Border x:Name="BorderPressed" Opacity="0" Background="Blue" VerticalAlignment="Stretch" CornerRadius="2" HorizontalAlignment="Stretch"/>
<Label Name="label1" Content="1" HorizontalAlignment="Left"></Label>
<Label Name="label2" Content="2" HorizontalAlignment="Right"></Label>
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" x:Name="MainContent" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="BorderPressed" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="BorderPressed" Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</Window.Resources>
<DockPanel>
<Button Content="Button" Height="23" Name="button1" Width="75" Style="{StaticResource SimpleButtonStyle}" Click="button1_Click"/>
</DockPanel>
Related
I have a WPF page with a TabControl in it, and I wanted to design the tabs to have a nice underline when selected and on mouse hover.
I've managed to do that but each tab has a different length, and it seems that I can't bind a property of the TabItem inside of its animation.
This is what i have done so far:
<TabControl Width="{Binding ActualWidth,
ElementName=cnvsMain}" Height="{Binding
ActualHeight, ElementName=cnvsMain}"
BorderThickness="0" >
<TabControl.Resources>
<Style TargetType="TabItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<StackPanel>
<Border Name="Border"
BorderThickness="1,1,1,0"
BorderBrush="Gainsboro"
CornerRadius="6,6,0,0"
Margin="2,0">
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="10,2"/>
</Border>
<Label Name="TabUnderline" Background="LimeGreen"
Margin=" 5, 0" Height="5" Width="0"/>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="TabUnderline"
Storyboard.TargetProperty="Width"
From="0" To="100"
Duration="0:0:0.1"
AutoReverse="False" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="TabUnderline"
Storyboard.TargetProperty="Width"
From="100" To="0" Duration="0:0:0.1"
AutoReverse="False" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
<TabItem Header="Rooms">
<StackPanel>
<Label Content="TODO: List all rooms" />
<Label Content="TODO: Create room button" />
</StackPanel>
</TabItem>
<TabItem Header="Statistics" />
<TabItem Header="Details" />
</TabControl>
It works great but there is one simple flaw:
The under line will always be 100 pixels (Or is it units?) wide, and each tab has its unique and different width. I've tried to replace the hard-coded 100 to {Binding ActualWidth} or using a RelativeSource to get the width of the TabItem, but I keep getting an exception everytime this page is being loaded because of a binding-error.
How can I bind a TabItem's property to a value inside its own animation? Is it even possible?
Based on the code below, is it possible to animate the transition from image1 to image2 on button IsMouseOverevent?
The following code works fine showing image1 as the upstate image and image2 as the hover image on a button but it does not animate the transition.
XAML Style
<Style x:Key="MainMenuButtonTemplate" TargetType="{x:Type Button}">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="button" CornerRadius="0"
Background="{TemplateBinding Background}"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}">
<TextBlock Text="{TemplateBinding Button.Content}"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="button" Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/App;component/Images/image2.png" Stretch="None"/>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
Usage
<Button x:Name="findRButton"
Style="{StaticResource MainMenuButtonTemplate}"
Margin="0,0,0,0"
Height="53"
Command="{Binding FindrViewCommand}" BorderBrush="{x:Null}" Foreground="White" BorderThickness="0">
<Button.Background>
<ImageBrush ImageSource="Images/image1.png" Stretch="None"/>
</Button.Background>
</Button>
Here is code that shows you how to do what you're looking for.
In order to use animations during triggers you must utilize the enter and exit actions of that trigger. You must also name BeginStoryboard so that you can stop it in other calls.
Review the code and if you have anymore questions let me know. This will fade from image1 to image2 and vice versa with mouse over / leave.
<Window x:Class="Question_Answer_WPF_App.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow"
Height="400"
Width="500">
<Window.Resources>
<Storyboard x:Key="mouseOverStoryboard"
Duration="00:00:00.5">
<DoubleAnimation Storyboard.TargetName="image1"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="00:00:00.5" />
<DoubleAnimation Storyboard.TargetName="image2"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="00:00:00.5" />
</Storyboard>
<Storyboard x:Key="mouseLeaveStoryboard"
Duration="00:00:00.5">
<DoubleAnimation Storyboard.TargetName="image1"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="00:00:00.5" />
<DoubleAnimation Storyboard.TargetName="image2"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="00:00:00.5" />
</Storyboard>
<Style x:Key="MainMenuButtonStyle"
TargetType="{x:Type Button}">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Image x:Name="image1"
Source="Images/image1.png" />
<Image x:Name="image2"
Source="Images/image2.png"
Opacity="0" />
<ContentPresenter />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Trigger.EnterActions>
<StopStoryboard BeginStoryboardName="mouseLeaveStoryboard" />
<BeginStoryboard Name="mouseOverStoryboard"
Storyboard="{StaticResource mouseOverStoryboard}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="mouseOverStoryboard" />
<BeginStoryboard Name="mouseLeaveStoryboard"
Storyboard="{StaticResource mouseLeaveStoryboard}" />
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
</Window.Resources>
<Grid>
<Button Style="{StaticResource MainMenuButtonStyle}"
Width="120"
Height="120" />
</Grid>
</Window>
I have a custom message box with two button 'Yes' and 'No'. Button 'Yes' is green and button 'No' is red.
I apply the same style for the two buttons through a xaml file defined separately as below:
MsgBoxButtonStyle.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="Button"
x:Key="MsgBoxButtonStyle">
<Setter Property="Background"
Value="Transparent" />
<Setter Property="TextBlock.TextAlignment"
Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="Border" CornerRadius="0"
BorderBrush="#000" BorderThickness="1,1,1,1"
Background="{TemplateBinding Background}">
<ContentPresenter x:Name="contentPresenter"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalAlignment}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
These two buttons are place in my WPF window as below:
<Window x:Class="My.XAML.Controls.Windows.WpfMessageBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/My.XAML;component/Styles/MsgBoxButtonStyle.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Button Name="btnYes" Content="Yes"
Click="Button_Click" Foreground="Black"
Style="{StaticResource MsgBoxButtonStyle}"
Background="#b6dbd6"
VerticalAlignment="Center" HorizontalAlignment="Stretch"
VerticalContentAlignment="Center" HorizontalContentAlignment="Center"/>
<Button Name="btnNo" Content="No"
Click="Button_Click" Foreground="Black"
Style="{StaticResource MsgBoxButtonStyle}"
Background="#dbb6b6"
VerticalAlignment="Center" HorizontalAlignment="Stretch"
VerticalContentAlignment="Center" HorizontalContentAlignment="Center" />
</Window>
Now, I would like to perform a nice effect when mouse is positioned over the buttons, some kind of blinking or whatever using storyboard and dependant on the color of the button.
Also I would like to put this storyboard within my existing style file MsgBoxButtonStyle.xaml and no put each storyboard in the window for each button, i want to share it.
How can I do this? some one can provide me a nice effect for buttons?
Just add triggers to the style. Here's an example to start you off.
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:0.250" To="0"
Storyboard.TargetProperty="BorderThickness" />
<DoubleAnimation Duration="0:0:0.550" To="120"
Storyboard.TargetProperty="Height" />
<DoubleAnimation Duration="0:0:0.550" To="120"
Storyboard.TargetProperty="Width" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:0.250" To="0"
Storyboard.TargetProperty="BorderThickness" />
<DoubleAnimation Duration="0:0:0.550" To="100"
Storyboard.TargetProperty="Height" />
<DoubleAnimation Duration="0:0:0.550" To="100"
Storyboard.TargetProperty="Width" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
I want to animate button shadow effect color when mouse enter border.
I try this code and is not working for me.
And I don't know where is the problem is?
<Style x:Name="HeaderButton" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="Border" BorderBrush="#FF550211" BorderThickness="0" CornerRadius="4">
<Border.Triggers>
<EventTrigger RoutedEvent="Border.MouseEnter">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Color" Storyboard.TargetName="MenuButtonShadow"
From="#FFFFFFFF" To="#FF000000" Duration="0:0:0.3"></ColorAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Border.Triggers>
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFAF1232" Offset="0" />
<GradientStop Color="#FFB60329" Offset="1" />
</LinearGradientBrush>
</Border.Background>
<ContentPresenter Margin="8, 0" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect x:Name="MenuButtonShadow" ShadowDepth="0" BlurRadius="4"></DropShadowEffect>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="Margin" Value="4"></Setter>
</Style>
From MSDN:
In Silverlight, the only event that you can use for an EventTrigger is the Loaded event. For other events, you should declare a storyboard in the Resources property, provide a Name value for the storyboard, and write an event handler that calls the Begin method on the named storyboard.
I imagine you could do something like this in your XAML (though I haven't tested it):
<Storyboard x:Name="MenuButtonShadowStoryboard">
<ColorAnimation Storyboard.TargetProperty="Color" Storyboard.TargetName="MenuButtonShadow"
From="#FFFFFFFF" To="#FF000000" Duration="0:0:0.3">
</ColorAnimation>
</Storyboard>
<ControlTemplate TargetType="Button">
<Border x:Name="Border" MouseEnter="Border_MouseEnter">
<!-- omitted for brevity -->
</Border>
</ControlTemplate>
And then your event handler would call the Begin method on the storyboard:
private void Border_MouseEnter(object sender, MouseEventArgs e)
{
MenuButtonShadowStoryboard.Begin();
}
You'll probably want to add something similar for the MouseLeave event, which makes the color go back to #FFFFFFFF.
The focus visual hint that wpf provides on Windows 7 is a dashed line, as such this:
Now, how can I change the way it looks? How can I control its appearence?
Thanks!
Try something like following
<Window x:Class="FocusVisualStyle.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="MyFocusVisualStyle">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="-2" StrokeThickness="1" Stroke="Red"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel Orientation="Horizontal" Height="24">
<TextBox Width="96"/>
<Button Content="Yes" Width="64" FocusVisualStyle="{DynamicResource MyFocusVisualStyle}"/>
<Button Content="No" Width="64" FocusVisualStyle="{DynamicResource MyFocusVisualStyle}"/>
</StackPanel>
You can customise to suit your liking. This is just a starting point.
Edit: Since so many people have liked this solution here is another example which changes focus visual style for all buttons and textboxes without explicit setting of FocusVisualStyle property for each control (see that DynamicResource thingy?) in xaml
Also it uses animation to change the colour of the focus rectangle.
Enjoy :)
<Window x:Class="FocusVisualStyle.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="MyFocusVisualStyle">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate >
<Rectangle Margin="-2" StrokeThickness="2" RadiusX="2" RadiusY="2" >
<Rectangle.Stroke>
<SolidColorBrush Color="Red" x:Name="RectangleStroke" />
</Rectangle.Stroke>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded" >
<BeginStoryboard>
<Storyboard>
<ColorAnimation From="Red"
To="Orange"
Duration="0:0:0.5"
RepeatBehavior="Forever"
Storyboard.TargetName="RectangleStroke"
Storyboard.TargetProperty="Color"/>
<DoubleAnimation To="3"
Duration="0:0:0.5"
RepeatBehavior="Forever"
Storyboard.TargetProperty="StrokeDashOffset" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource MyFocusVisualStyle}" />
</Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="FocusVisualStyle" Value="{StaticResource MyFocusVisualStyle}" />
</Style>
</Window.Resources>
<StackPanel Orientation="Horizontal" Height="24">
<TextBox Width="96"/>
<Button Content="Yes" Width="64" />
<Button Content="No" Width="64" />
</StackPanel>
Here you see that I have styles for Button and TextBox which set the property FocusVisualStyle for all the buttons and text boxes in this window.