All the controls missing in WPF. Over 1 million downloads.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
3.6 KiB

/*************************************************************************************
Extended WPF Toolkit
Copyright (C) 2007-2013 Xceed Software Inc.
This program is provided to you under the terms of the Microsoft Public
License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
For more features, controls, and fast professional support,
pick up the Plus Edition at http://xceed.com/wpf_toolkit
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
***********************************************************************************/
using System.Windows;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
namespace Xceed.Wpf.Toolkit
{
public class MagnifierAdorner : Adorner
{
#region Members
private Magnifier _magnifier;
private Point _currentMousePosition;
#endregion
#region Constructors
public MagnifierAdorner( UIElement element, Magnifier magnifier )
: base( element )
{
_magnifier = magnifier;
UpdateViewBox();
AddVisualChild( _magnifier );
Loaded += ( s, e ) => InputManager.Current.PostProcessInput += OnProcessInput;
Unloaded += ( s, e ) => InputManager.Current.PostProcessInput -= OnProcessInput;
}
#endregion
#region Private/Internal methods
private void OnProcessInput( object sender, ProcessInputEventArgs e )
{
Point pt = Mouse.GetPosition( this );
if( _currentMousePosition == pt )
return;
_currentMousePosition = pt;
UpdateViewBox();
InvalidateArrange();
}
internal void UpdateViewBox()
{
var viewBoxLocation = CalculateViewBoxLocation();
_magnifier.ViewBox = new Rect( viewBoxLocation, _magnifier.ViewBox.Size );
}
private Point CalculateViewBoxLocation()
{
double offsetX = 0, offsetY = 0;
Point adorner = Mouse.GetPosition( this );
Point element = Mouse.GetPosition( AdornedElement );
offsetX = element.X - adorner.X;
offsetY = element.Y - adorner.Y;
//An element will use the offset from its parent (StackPanel, Grid, etc.) to be rendered.
//When this element is put in a VisualBrush, the element will draw with that offset applied.
//To fix this: we add that parent offset to Magnifier location.
Vector parentOffsetVector = VisualTreeHelper.GetOffset( _magnifier.Target );
Point parentOffset = new Point( parentOffsetVector.X, parentOffsetVector.Y );
double left = _currentMousePosition.X - ( ( _magnifier.ViewBox.Width / 2 ) + offsetX ) + parentOffset.X;
double top = _currentMousePosition.Y - ( ( _magnifier.ViewBox.Height / 2 ) + offsetY ) + parentOffset.Y;
return new Point( left, top );
}
#endregion
#region Overrides
protected override Visual GetVisualChild( int index )
{
return _magnifier;
}
protected override int VisualChildrenCount
{
get
{
return 1;
}
}
protected override Size MeasureOverride( Size constraint )
{
_magnifier.Measure( constraint );
return base.MeasureOverride( constraint );
}
protected override Size ArrangeOverride( Size finalSize )
{
double x = _currentMousePosition.X - ( _magnifier.Width / 2 );
double y = _currentMousePosition.Y - ( _magnifier.Height / 2 );
_magnifier.Arrange( new Rect( x, y, _magnifier.Width, _magnifier.Height ) );
return base.ArrangeOverride( finalSize );
}
#endregion
}
}