// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
using System.Diagnostics;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
namespace System.Windows.Controls{
/// <summary>
/// Class to encapsulate drag behavior for a UIElement
/// </summary>
internal class DragValidator
{
private UIElement _targetElement;
private Point _start;
private bool _draggingActive;
/// <summary>
/// Occurs when a drag operation has started
/// </summary>
public event EventHandler<DragStartedEventArgs> DragStartedEvent;
/// <summary>
/// Occurs when a drag operation has completed
/// </summary>
public event EventHandler<DragCompletedEventArgs> DragCompletedEvent;
/// <summary>
/// Occurs when a drag operation has progressed
/// </summary>
public event EventHandler<DragDeltaEventArgs> DragDeltaEvent;
/// <summary>
/// Create an instance of the DragValidator class
/// </summary>
/// <param name="targetElement">UIElement that represents the source of the drag operation</param>
public DragValidator(UIElement targetElement)
{
Debug.Assert(targetElement != null);
_targetElement = targetElement;
_targetElement.MouseLeftButtonDown += new MouseButtonEventHandler(TargetElement_MouseLeftButtonDown);
_targetElement.MouseLeftButtonUp += new MouseButtonEventHandler(TargetElement_MouseLeftButtonUp);
_targetElement.MouseMove += new MouseEventHandler(TargetElement_MouseMove);
}
/// <summary>
/// Handle the MouseMove event for the UIElement to update the drag operation
/// </summary>
private void TargetElement_MouseMove(object sender, MouseEventArgs e)
{
if (_draggingActive)
{
OnDragDelta(e);
}
}
/// <summary>
/// Handle the MouseLeftButtonUp event for the UIElement to complete the drag operation
/// </summary>
private void TargetElement_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
_targetElement.ReleaseMouseCapture();
_draggingActive = false;
OnDragCompleted(e, false);
}
/// <summary>
/// Handle the MouseLeftButtonDown event for the UIElement to start a drag operation
/// </summary>
private void TargetElement_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
_start = e.GetPosition(_targetElement);
if (_targetElement.RenderTransform != null)
{
_start = _targetElement.RenderTransform.Transform(_start);
}
_draggingActive = _targetElement.CaptureMouse();
// Only start the drag operation if CaptureMouse succeeded
if (_draggingActive)
{
OnDragStarted();
}
}
/// <summary>
/// Invoke the DragStartedEvent handlers
/// </summary>
private void OnDragStarted()
{
EventHandler<DragStartedEventArgs> handler = this.DragStartedEvent;
if (handler != null)
{
handler(_targetElement, new DragStartedEventArgs(0.0, 0.0));
}
}
/// <summary>
/// Invoke the DragDeltaEvent handlers
/// </summary>
private void OnDragDelta(MouseEventArgs e)
{
EventHandler<DragDeltaEventArgs> handler = this.DragDeltaEvent;
if (handler != null)
{
Point p = e.GetPosition(_targetElement);
if (_targetElement.RenderTransform != null)
{
p = _targetElement.RenderTransform.Transform(p);
}
handler(_targetElement, new DragDeltaEventArgs(p.X - _start.X, p.Y - _start.Y));
}
}
/// <summary>
/// Invoke the DragCompletedEvent handlers
/// </summary>
private void OnDragCompleted(MouseEventArgs e, bool canceled)
{
EventHandler<DragCompletedEventArgs> handler = this.DragCompletedEvent;
if (handler != null)
{
Point endPoint;
if (canceled)
{
endPoint = new Point();
}
else
{
Point p = e.GetPosition(_targetElement);
if (_targetElement.RenderTransform != null)
{
p = _targetElement.RenderTransform.Transform(p);
}
endPoint = new Point(p.X - _start.X, p.Y - _start.Y);
}
handler(_targetElement, new DragCompletedEventArgs(endPoint.X, endPoint.Y, canceled));
}
}
}
}
|