2011-07-14 75 views
1

我想實現像樣式的轉盤,我發現很難用鼠標移動事件移動磁盤。用鼠標移動事件旋轉圖像

這是我的XAML代碼

<!-- Disk rotating code --> 
     <StackPanel x:Name="disk" Margin="0,-60,0,0"> 
      <StackPanel.Resources> 
       <Storyboard x:Name="myStoryboard"> 
        <DoubleAnimation Storyboard.TargetName="myTransform" 
            Storyboard.TargetProperty="Angle" 
            From="0" To="360" Duration="0:0:5" 
            RepeatBehavior="Forever"> 
        </DoubleAnimation> 
       </Storyboard> 
      </StackPanel.Resources> 
      <Rectangle x:Name="ttbg" Margin="5,200,30,0" Stroke="Black" StrokeThickness="0" RenderTransformOrigin="0.503,0.503" Height="420" Width="420" MouseLeftButtonDown="press_down" MouseLeftButtonUp="press_up" MouseMove="press_move" > 
      <Rectangle.Fill> 
        <ImageBrush ImageSource="Images/ttbg.png" Stretch="Uniform" /> 
      </Rectangle.Fill> 
       <Rectangle.RenderTransform> 
        <TransformGroup> 
         <RotateTransform x:Name="myTransform" /> 
        </TransformGroup> 
       </Rectangle.RenderTransform> 
      </Rectangle> 
     </StackPanel> 

這是我的C#代碼從一個新手

回答

1

private void press_down(object sender, System.Windows.Input.MouseButtonEventArgs e) 
    { 
     // TODO: Add event handler implementation here. 

    } 

    private void press_up(object sender, System.Windows.Input.MouseButtonEventArgs e) 
    { 
     // TODO: Add event handler implementation here. 
    } 

    private void press_move(object sender, System.Windows.Input.MouseEventArgs e) 
    { 
     // TODO: Add event handler implementation here. 

    } 

問題這是一個有點棘手,需要一些編碼。但我會試一試。

首先,我更改了XAML,以便我將使用Canvas而不是您使用的StackPanel。在這種情況下,我更喜歡Canvas,因爲它允許我使用絕對座標定位轉盤圖像,以便我確切知道轉盤中心的位置。在XAML現在看起來是這樣的:

<UserControl x:Class="TurnTable.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" 
    d:DesignHeight="300" d:DesignWidth="400" 
    > 

    <Canvas x:Name="LayoutRoot" Background="White"> 
     <!-- Disk rotating code --> 
     <Canvas.Resources> 
      <Storyboard x:Name="myStoryboard"> 
       <DoubleAnimation x:Name="angleAnimation" Storyboard.TargetName="myTransform" 
            Storyboard.TargetProperty="Angle" 
            From="0" To="0" Duration="0:0:1" 
            > 
        <DoubleAnimation.EasingFunction> 
         <CubicEase /> 
        </DoubleAnimation.EasingFunction> 
       </DoubleAnimation> 
      </Storyboard> 
     </Canvas.Resources> 
     <Rectangle x:Name="ttbg" Canvas.Left="100" Canvas.Top="100" Stroke="Black" StrokeThickness="0" RenderTransformOrigin="0.5,0.5" Height="420" Width="420" MouseLeftButtonDown="press_down" MouseLeftButtonUp="press_up" MouseMove="press_move" > 
      <Rectangle.Fill> 
       <ImageBrush ImageSource="Images/ttbg.png" Stretch="Uniform" /> 
      </Rectangle.Fill> 
      <Rectangle.RenderTransform> 
       <TransformGroup> 
        <RotateTransform x:Name="myTransform" /> 
       </TransformGroup> 
      </Rectangle.RenderTransform> 
     </Rectangle> 
    </Canvas> 
</UserControl> 

另外請注意,我把故事板1秒的時間,我給它一個EasingFunction給動畫一個漂亮的外觀和感覺。

在用戶控件的代碼隱藏中,我使用Math.Atan函數來計算鼠標移動時轉動轉盤的角度。我正在使用鼠標相對於轉盤中心的座標來確定要饋送到Math.Atan的值。該代碼最終看起來如下:

namespace TurnTable 
{ 
    public partial class MainPage : UserControl 
    { 
     Point _centerOfTurnTable; 
     Point _startMousePosition; 
     Point _lastMousePosition; 
     bool _isMouseCaptured = false; 
     double _deltaAngle; 

     public MainPage() 
     { 
      InitializeComponent(); 
     } 

     private void press_down(object sender, System.Windows.Input.MouseButtonEventArgs e) 
     { 
      _centerOfTurnTable = new Point 
      (
       Canvas.GetLeft(ttbg) + ttbg.ActualWidth/2d, 
       Canvas.GetTop(ttbg) + ttbg.ActualHeight/2d 
      ); 

      myStoryboard.Pause(); 

      _startMousePosition = e.GetPosition(this); 
      _isMouseCaptured = true; 
      _lastMousePosition = _startMousePosition; 
     } 

     private void press_up(object sender, System.Windows.Input.MouseButtonEventArgs e) 
     { 
      if (_isMouseCaptured) 
      { 
       _isMouseCaptured = false; 

       angleAnimation.From = myTransform.Angle; 
       angleAnimation.To = myTransform.Angle + _deltaAngle * 100; 
       _deltaAngle = 0; 
       myStoryboard.Begin(); 
      } 
     } 

     private void press_move(object sender, System.Windows.Input.MouseEventArgs e) 
     { 
      Point currentMousePosition = e.GetPosition(this); 
      if (_isMouseCaptured && Math.Abs(currentMousePosition.X - _centerOfTurnTable.X) > 5) 
      { 
       _deltaAngle = GetAngleDelta(currentMousePosition); 

       myTransform.Angle += _deltaAngle; 
       _lastMousePosition = currentMousePosition; 
      } 
     } 

     private double GetAngleDelta(Point currentMousePosition) 
     { 
      double lastAngleDegrees = GetAngleDegrees(_lastMousePosition); 
      double newAngleDegrees = GetAngleDegrees(currentMousePosition); 

      if (Math.Sign(lastAngleDegrees) != Math.Sign(newAngleDegrees)) 
      { 
       lastAngleDegrees = newAngleDegrees; 
      } 
      double delta = newAngleDegrees - lastAngleDegrees; 
      return delta; 
     } 

     private double GetAngleDegrees(Point position) 
     { 
      return 180d/Math.PI * Math.Atan((position.Y - _centerOfTurnTable.Y)/(position.X - _centerOfTurnTable.X)); 
     } 
    } 
} 

的代碼可以讓你把轉盤上並按下鼠標時的動畫將開始允許轉盤慢慢道來完全停止這給它一個很好的接觸。

+0

感謝jakob的回覆,試着讓你的代碼在angleAnimation.From = myTransform.Angle; angleAnimation.To = myTransform.Angle + _deltaAngle * 100; angleAnimation對於當前上下文不存在。 – Dharmang

+0

如果你看看我的XAML,你會看到angleAnimation是DoubleAnimation的名字。所以你必須在XAML中定義angleAnimation。 –