Daily Demo: Silverlight Behavior for 3D Hover Effect
Behaviors are great new feature in Silverlight 3 (or better in Blend 3) for adding “features” to a control without coding. My favorite sample is a hover effect, that applies when a mouse enters a control.
XAML-Code:
<UserControl
x:Class="Hover3DBehavior.MainPage"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:TheOliver_Controls="clr-namespace:TheOliver.Controls"
d:DesignHeight="300"
d:DesignWidth="400"
xmlns:dataInput="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input">
<Grid
x:Name="LayoutRoot"
Background="White">
<Button
Content="Button"
Height="23"
HorizontalAlignment="Left"
Margin="89,78,0,0"
Name="button1"
VerticalAlignment="Top"
Width="75">
<i:Interaction.Behaviors>
<TheOliver_Controls:Hover3DBehavior />
</i:Interaction.Behaviors>
</Button>
<dataInput:Label
Height="50"
HorizontalAlignment="Left"
Margin="274,64,0,0"
Name="label1"
VerticalAlignment="Top"
Width="100"
Content="Hello World">
<i:Interaction.Behaviors>
<TheOliver_Controls:Hover3DBehavior />
</i:Interaction.Behaviors>
</dataInput:Label>
<RadioButton
Content="RadioButton"
Height="16"
HorizontalAlignment="Left"
Margin="12,133,0,0"
Name="radioButton1"
VerticalAlignment="Top">
<i:Interaction.Behaviors>
<TheOliver_Controls:Hover3DBehavior />
</i:Interaction.Behaviors>
</RadioButton>
</Grid>
</UserControl>
Source-Code:
// Copyright © Microsoft Corporation. All Rights Reserved.
// This code released under the terms of the
// Microsoft Public License (MS-PL, https://opensource.org/licenses/ms-pl.html.)
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interactivity;
using System.Windows.Media;
using System.Windows.Media.Animation;
namespace TheOliver.Controls
{
public class Hover3DBehavior : Behavior<UIElement>
{
PlaneProjection _planeProjection;
public Hover3DBehavior()
: base()
{
}
Storyboard _hoverMe;
Storyboard _unhoverMe;
public double ZHoverValue
{
get { return (double)GetValue(ZHoverValueProperty); }
set { SetValue(ZHoverValueProperty, value); }
}
public static readonly DependencyProperty ZHoverValueProperty =
DependencyProperty.Register("ZHoverValue", typeof(double), typeof(Hover3DBehavior),
new PropertyMetadata(500.0, null));
public int HoverDurationMilliseconds
{
get { return (int)GetValue(HoverDurationMillisecondsProperty); }
set { SetValue(HoverDurationMillisecondsProperty, value); }
}
public static readonly DependencyProperty HoverDurationMillisecondsProperty =
DependencyProperty.Register("HoverDurationMilliseconds"
, typeof(int)
, typeof(Hover3DBehavior),
new PropertyMetadata(200, null));
#region Overrides
protected override void OnAttached()
{
base.OnAttached();
_planeProjection = new PlaneProjection();
this.AssociatedObject.Projection = _planeProjection;
if (!DesignerProperties.GetIsInDesignMode(this))
{
_hoverMe = new Storyboard();
DoubleAnimation da1 = new DoubleAnimation();
_hoverMe.Children.Add(da1);
da1.Duration = new Duration(new System.TimeSpan(0, 0, 0, 0, HoverDurationMilliseconds));
da1.To = this.ZHoverValue;
Storyboard.SetTarget(da1, this.AssociatedObject);
Storyboard.SetTargetProperty(da1, new PropertyPath("(UIElement.Projection).(PlaneProjection.LocalOffsetZ)"));
DoubleAnimation da2 = new DoubleAnimation();
BounceEase be2 = new BounceEase();
be2.EasingMode = EasingMode.EaseOut;
be2.Bounces = 3;
da2.EasingFunction = be2;
_unhoverMe = new Storyboard();
_unhoverMe.Children.Add(da2);
da2.Duration = new Duration(new System.TimeSpan(0, 0, 0, 0, 1000));
da2.To = 0.0;
Storyboard.SetTarget(da2, this.AssociatedObject);
Storyboard.SetTargetProperty(da2, new PropertyPath("(UIElement.Projection).(PlaneProjection.LocalOffsetZ)"));
if ((this.AssociatedObject as FrameworkElement).Resources.Contains("hoverme"))
{
(this.AssociatedObject as FrameworkElement).Resources.Remove("hoverme");
}
(this.AssociatedObject as FrameworkElement).Resources.Add("hoverme", _hoverMe);
if ((this.AssociatedObject as FrameworkElement).Resources.Contains("unhoverme"))
{
(this.AssociatedObject as FrameworkElement).Resources.Remove("unhoverme");
}
(this.AssociatedObject as FrameworkElement).Resources.Add("unhoverme", _unhoverMe);
}
this.AssociatedObject.MouseEnter += AssociatedObject_MouseEnter;
this.AssociatedObject.MouseLeave += AssociatedObject_MouseLeave;
}
protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.Projection = null;
_planeProjection = null;
this.AssociatedObject.MouseEnter -= AssociatedObject_MouseEnter;
this.AssociatedObject.MouseLeave -= AssociatedObject_MouseLeave;
}
#endregion
#region Events
void AssociatedObject_MouseLeave(object sender, MouseEventArgs e)
{
_unhoverMe.Begin();
}
void AssociatedObject_MouseEnter(object sender, MouseEventArgs e)
{
//FrameworkElement e1 = this.AssociatedObject as FrameworkElement;
//if (e1.Parent is Panel)
//{
// Panel p = e1.Parent as Panel;
// if (p != null)
// {
// UIElement element = this.AssociatedObject;
// element.SetValue(UIElement.
// p.Children.Remove(element);
// p.Children.Add(element);
// }
//}
_hoverMe.Begin();
}
#endregion
}
}