diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Magnifier/Converters/BorderThicknessToStrokeThicknessConverter.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Magnifier/Converters/BorderThicknessToStrokeThicknessConverter.cs
new file mode 100644
index 00000000..1f672cda
--- /dev/null
+++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Magnifier/Converters/BorderThicknessToStrokeThicknessConverter.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Windows.Data;
+using System.Windows;
+
+namespace Microsoft.Windows.Controls.Mag.Converters
+{
+ internal class BorderThicknessToStrokeThicknessConverter : IValueConverter
+ {
+ #region IValueConverter Members
+
+ public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ Thickness thickness = (Thickness)value;
+ return (thickness.Bottom + thickness.Left + thickness.Right + thickness.Top) / 4;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+
+ #endregion
+ }
+}
diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Magnifier/Converters/RadiusConverter.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Magnifier/Converters/RadiusConverter.cs
new file mode 100644
index 00000000..532a3552
--- /dev/null
+++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Magnifier/Converters/RadiusConverter.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Windows.Data;
+
+namespace Microsoft.Windows.Controls.Mag.Converters
+{
+ internal class RadiusConverter : IValueConverter
+ {
+ #region IValueConverter Members
+
+ public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ return (double)value * 2;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+
+ #endregion
+ }
+}
diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Magnifier/Magnifier.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Magnifier/Magnifier.cs
new file mode 100644
index 00000000..2ea13e1b
--- /dev/null
+++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Magnifier/Magnifier.cs
@@ -0,0 +1,166 @@
+using System;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace Microsoft.Windows.Controls
+{
+ public class Magnifier : Control
+ {
+ #region Properties
+
+ #region DefaultSize
+
+ internal Size DefaultSize
+ {
+ get
+ {
+ return new Size(2 * Radius, 2 * Radius);
+ }
+ }
+
+ #endregion //DefaultSize
+
+ #region MagnifierWidth
+
+ public static readonly DependencyProperty MagnifierWidthProperty = DependencyProperty.Register("MagnifierWidth", typeof(double), typeof(Magnifier), new UIPropertyMetadata(50.0));
+ internal double MagnifierWidth
+ {
+ get { return (double)GetValue(MagnifierWidthProperty); }
+ set { SetValue(MagnifierWidthProperty, value); }
+ }
+
+ #endregion //MagnifierWidth
+
+ #region MagnifierHeight
+
+ public static readonly DependencyProperty MagnifierHeightProperty = DependencyProperty.Register("MagnifierHeight", typeof(double), typeof(Magnifier), new UIPropertyMetadata(50.0));
+ internal double MagnifierHeight
+ {
+ get { return (double)GetValue(MagnifierHeightProperty); }
+ set { SetValue(MagnifierHeightProperty, value); }
+ }
+
+ #endregion //MagnifierWidth
+
+ #region Radius
+
+ public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register("Radius", typeof(double), typeof(Magnifier), new FrameworkPropertyMetadata(50.0, new PropertyChangedCallback(OnRadiusPropertyChanged)));
+ public double Radius
+ {
+ get { return (double)GetValue(RadiusProperty); }
+ set { SetValue(RadiusProperty, value); }
+ }
+
+ private static void OnRadiusPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ Magnifier m = (Magnifier)d;
+ m.OnRadiusChanged(e);
+ }
+
+ protected virtual void OnRadiusChanged(DependencyPropertyChangedEventArgs e)
+ {
+ ResolveViewBox();
+ }
+
+ #endregion //Radius
+
+ #region Target
+
+ public static readonly DependencyProperty TargetProperty = DependencyProperty.Register("Target", typeof(UIElement), typeof(Magnifier));
+ public UIElement Target
+ {
+ get { return (UIElement)GetValue(TargetProperty); }
+ set { SetValue(TargetProperty, value); }
+ }
+
+ #endregion //Target
+
+ #region ViewBox
+
+ public static readonly DependencyProperty ViewBoxProperty = DependencyProperty.Register("ViewBox", typeof(Rect), typeof(Magnifier), new FrameworkPropertyMetadata(default(Rect)));
+ internal Rect ViewBox
+ {
+ get { return (Rect)GetValue(ViewBoxProperty); }
+ set { SetValue(ViewBoxProperty, value); }
+ }
+
+ #endregion //ViewBox
+
+ #region ZoomFactor
+
+ public static readonly DependencyProperty ZoomFactorProperty = DependencyProperty.Register("ZoomFactor", typeof(double), typeof(Magnifier), new FrameworkPropertyMetadata(0.5, OnZoomFactorPropertyChanged, OnCoerceZoomFactorProperty));
+ public double ZoomFactor
+ {
+ get { return (double)GetValue(ZoomFactorProperty); }
+ set { SetValue(ZoomFactorProperty, value); }
+ }
+
+ private static void OnZoomFactorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ Magnifier m = (Magnifier)d;
+ m.OnZoomFactorChanged(e);
+ }
+
+ protected virtual void OnZoomFactorChanged(DependencyPropertyChangedEventArgs e)
+ {
+ ResolveViewBox();
+ }
+
+ private static object OnCoerceZoomFactorProperty(DependencyObject d, object value)
+ {
+ Magnifier m = (Magnifier)d;
+ return m.OnCoerceZoomFactor(value);
+ }
+
+ protected virtual object OnCoerceZoomFactor(object value)
+ {
+ double zoomFactor = (double)value;
+
+ if (zoomFactor > 1)
+ zoomFactor = 1;
+ else if (zoomFactor < 0)
+ zoomFactor = 0;
+
+ return zoomFactor;
+ }
+
+ #endregion //ZoomFactor
+
+ #endregion //Properties
+
+ #region Constructors
+
+ ///
+ /// Initializes static members of the class.
+ ///
+ static Magnifier()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(Magnifier), new FrameworkPropertyMetadata(typeof(Magnifier)));
+ }
+
+ public Magnifier()
+ {
+ ResolveViewBox();
+ }
+
+ #endregion
+
+ #region Methods
+
+ private void ResolveViewBox()
+ {
+ double correction = (BorderThickness.Bottom + BorderThickness.Left + BorderThickness.Right + BorderThickness.Top == 0) ? 1 : 0;
+
+ double width = DefaultSize.Width * ZoomFactor;
+ double height = DefaultSize.Height * ZoomFactor;
+
+ MagnifierWidth = DefaultSize.Width - correction;
+ MagnifierHeight = DefaultSize.Height - correction;
+
+ ViewBox = new Rect(ViewBox.Location, new Size(width, height));
+ }
+
+ #endregion //Methods
+
+ }
+}
diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Magnifier/MagnifierAdorner.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Magnifier/MagnifierAdorner.cs
new file mode 100644
index 00000000..2b31e80f
--- /dev/null
+++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Magnifier/MagnifierAdorner.cs
@@ -0,0 +1,96 @@
+using System;
+using System.Windows.Documents;
+using System.Windows;
+using System.Windows.Input;
+using System.Windows.Media;
+
+namespace Microsoft.Windows.Controls
+{
+ public class MagnifierAdorner : Adorner
+ {
+ #region Members
+
+ private Magnifier _magnifier;
+ private Point _currentMousePosition;
+
+ #endregion
+
+ #region Constructors
+
+ public MagnifierAdorner(UIElement element, Magnifier magnifier)
+ : base(element)
+ {
+ InputManager.Current.PostProcessInput += Current_PostProcessInput;
+ _magnifier = magnifier;
+ UpdateViewBox();
+ AddVisualChild(_magnifier);
+ }
+
+ #endregion
+
+ #region Private/Internal methods
+
+ private void Current_PostProcessInput(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;
+
+ double left = _currentMousePosition.X - ((_magnifier.ViewBox.Width / 2) + offsetX);
+ double top = _currentMousePosition.Y - ((_magnifier.ViewBox.Height / 2) + offsetY);
+ 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.DefaultSize.Width / 2);
+ double y = _currentMousePosition.Y - (_magnifier.DefaultSize.Height / 2);
+ _magnifier.Arrange(new Rect(x, y, _magnifier.DefaultSize.Width, _magnifier.DefaultSize.Height));
+ return base.ArrangeOverride(finalSize);
+ }
+
+ #endregion
+ }
+}
diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Magnifier/MagnifierManager.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Magnifier/MagnifierManager.cs
new file mode 100644
index 00000000..eaaa2c7e
--- /dev/null
+++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Magnifier/MagnifierManager.cs
@@ -0,0 +1,98 @@
+using System;
+using System.Windows;
+using System.Windows.Documents;
+using System.Windows.Input;
+
+namespace Microsoft.Windows.Controls
+{
+ public class MagnifierManager : DependencyObject
+ {
+ #region Members
+
+ private MagnifierAdorner _adorner;
+ private UIElement _element;
+
+ #endregion //Members
+
+ #region Properties
+
+ public static readonly DependencyProperty CurrentProperty = DependencyProperty.RegisterAttached("Magnifier", typeof(Magnifier), typeof(UIElement), new FrameworkPropertyMetadata(null, OnMagnifierChanged));
+ public static void SetMagnifier(UIElement element, Magnifier value)
+ {
+ element.SetValue(CurrentProperty, value);
+ }
+ public static Magnifier GetMagnifier(UIElement element)
+ {
+ return (Magnifier)element.GetValue(CurrentProperty);
+ }
+
+ private static void OnMagnifierChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ UIElement target = d as UIElement;
+
+ if (target == null)
+ throw new ArgumentException("Magnifier can only be attached to a UIElement.");
+
+ MagnifierManager manager = new MagnifierManager();
+ manager.AttachToMagnifier(target, e.NewValue as Magnifier);
+ }
+
+ #endregion //Properties
+
+ #region Event Handlers
+
+ void Element_MouseLeave(object sender, MouseEventArgs e)
+ {
+ HideAdorner();
+ }
+
+ void Element_MouseEnter(object sender, MouseEventArgs e)
+ {
+ ShowAdorner();
+ }
+
+ #endregion //Event Handlers
+
+ #region Methods
+
+ private void AttachToMagnifier(UIElement element, Magnifier magnifier)
+ {
+ _element = element;
+ _element.MouseEnter += Element_MouseEnter;
+ _element.MouseLeave += Element_MouseLeave;
+
+ magnifier.Target = _element;
+
+ _adorner = new MagnifierAdorner(_element, magnifier);
+ }
+
+ void ShowAdorner()
+ {
+ VerifyAdornerLayer();
+ _adorner.Visibility = Visibility.Visible;
+ }
+
+ bool VerifyAdornerLayer()
+ {
+ if (_adorner.Parent != null)
+ return true;
+
+ AdornerLayer layer = AdornerLayer.GetAdornerLayer(_element);
+ if (layer == null)
+ return false;
+
+ layer.Add(_adorner);
+ return true;
+ }
+
+ void HideAdorner()
+ {
+ if (_adorner.Visibility == Visibility.Visible)
+ {
+ _adorner.Visibility = Visibility.Collapsed;
+ }
+ }
+
+ #endregion //Methods
+ }
+}
diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml
index b2b3f717..5694227a 100644
--- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml
+++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml
@@ -1,7 +1,8 @@
+ xmlns:local="clr-namespace:Microsoft.Windows.Controls"
+ xmlns:magConverters="clr-namespace:Microsoft.Windows.Controls.Mag.Converters">
@@ -1106,4 +1107,37 @@
+
+
+
+
+
+
+
+
+
diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj
index 738ae7e2..ed35e03f 100644
--- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj
+++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj
@@ -76,6 +76,11 @@
+
+
+
+
+