Daily Demo: Silverlight Mouse 3D Behavior
A very cool new feature in Silverlight 3 is the support of perspective 3D. And now image what you can do with 3D, your Mouse and Behaviors. Apply 3D capabilities to every control you like.
Ta da … the Silverlight Mouse 3D Behavior
XAML-Code
<UserControl
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"
x:Class="Mouse3DBehavior.MainPage"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid
x:Name="LayoutRoot"
Background="White">
<Image
Source="20080815_114932.jpg"
Stretch="Fill">
<i:Interaction.Behaviors>
<TheOliver_Controls:Mouse3DBehavior />
</i:Interaction.Behaviors>
</Image>
</Grid>
</UserControl>
Sourcecode
// 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.Windows;
using System.Windows.Input;
using System.Windows.Interactivity;
using System.Windows.Media;
namespace TheOliver.Controls
{
public class Mouse3DBehavior : Behavior<UIElement>
{
PlaneProjection _planeProjection;
bool _buttonPressed = false;
Point _originPoint;
UIElement _target;
FrameworkElement _control;
UIElement _targetParent;
double _controlHeight;
double _controlWidth;
protected override void OnAttached()
{
base.OnAttached();
_target = this.AssociatedObject;
_control = _target as FrameworkElement;
_control.LayoutUpdated += (s, e) =>
{
_targetParent = _control.Parent as UIElement;
_planeProjection = new PlaneProjection();
_target.Projection = _planeProjection;
_targetParent.MouseLeftButtonDown += new MouseButtonEventHandler(AssociatedObject_MouseLeftButtonDown);
_targetParent.MouseLeftButtonUp += new MouseButtonEventHandler(AssociatedObject_MouseLeftButtonUp);
_targetParent.MouseMove += new MouseEventHandler(AssociatedObject_MouseMove);
_targetParent.MouseLeave += new MouseEventHandler(AssociatedObject_MouseLeave);
_controlHeight = (_targetParent as FrameworkElement).ActualHeight;
_controlWidth = (_targetParent as FrameworkElement).ActualWidth;
};
}
void AssociatedObject_MouseLeave(object sender, MouseEventArgs e)
{
_buttonPressed = false;
}
void AssociatedObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
_target.CaptureMouse();
_originPoint = GetPoint(e);
_buttonPressed = true;
}
void AssociatedObject_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
_buttonPressed = false;
_target.ReleaseMouseCapture();
}
void AssociatedObject_MouseMove(object sender, MouseEventArgs e)
{
if (_buttonPressed)
{
PlaneProjection pp = _target.Projection as PlaneProjection;
Point pt = GetPoint(e);
double widthPixPerAngle = _controlWidth / 720;
double heightPixPerAngle = _controlHeight / 720;
double diffY = (pt.X - _controlWidth / 2) * widthPixPerAngle;
double diffX = (pt.Y - _controlHeight / 2) * heightPixPerAngle;
_originPoint = pt;
if (YEnable)
{
pp.RotationY = diffY;
}
if (XEnable)
{
pp.RotationX = diffX;
}
}
}
private Point GetPoint(MouseEventArgs e)
{
Point point = e.GetPosition(_targetParent);
return point;
}
protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.Projection = null;
_targetParent.MouseLeftButtonDown -= new MouseButtonEventHandler(AssociatedObject_MouseLeftButtonDown);
_targetParent.MouseLeftButtonUp -= new MouseButtonEventHandler(AssociatedObject_MouseLeftButtonUp);
_targetParent.MouseMove -= new MouseEventHandler(AssociatedObject_MouseMove);
_targetParent.MouseLeave -= new MouseEventHandler(AssociatedObject_MouseLeave);
}
public double MoveFactor
{
get { return (double)GetValue(MoveFactorProperty); }
set { SetValue(MoveFactorProperty, value); }
}
public static readonly DependencyProperty MoveFactorProperty =
DependencyProperty.Register(
"MoveFactor",
typeof(double),
typeof(Mouse3DBehavior),
new PropertyMetadata(1.0));
public bool XEnable
{
get { return (bool)GetValue(XEnableProperty); }
set { SetValue(XEnableProperty, value); }
}
public static readonly DependencyProperty XEnableProperty =
DependencyProperty.Register(
"XEnable",
typeof(bool),
typeof(Mouse3DBehavior),
new PropertyMetadata(true));
public bool YEnable
{
get { return (bool)GetValue(YEnableProperty); }
set { SetValue(YEnableProperty, value); }
}
public static readonly DependencyProperty YEnableProperty =
DependencyProperty.Register(
"YEnable",
typeof(bool),
typeof(Mouse3DBehavior),
new PropertyMetadata(true));
}
}