123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- using System.Windows;
- using System.Windows.Documents;
- using System.Windows.Input;
- using System.Windows.Media;
- using HandyControl.Data;
- using HandyControl.Interactivity;
- using HandyControl.Tools;
- using HandyControl.Tools.Extension;
- namespace HandyControl.Controls;
- [TemplatePart(Name = ElementVisualBrush, Type = typeof(VisualBrush))]
- public class Magnifier : AdornerElement
- {
- private AdornerContainer _adornerContainer;
- private Size _viewboxSize;
- private const string ElementVisualBrush = "PART_VisualBrush";
- private VisualBrush _visualBrush = new();
- private readonly TranslateTransform _translateTransform;
- public static readonly DependencyProperty HorizontalOffsetProperty = DependencyProperty.Register(
- nameof(HorizontalOffset), typeof(double), typeof(Magnifier), new PropertyMetadata(ValueBoxes.Double0Box));
- public double HorizontalOffset
- {
- get => (double) GetValue(HorizontalOffsetProperty);
- set => SetValue(HorizontalOffsetProperty, value);
- }
- public static readonly DependencyProperty VerticalOffsetProperty = DependencyProperty.Register(
- nameof(VerticalOffset), typeof(double), typeof(Magnifier), new PropertyMetadata(ValueBoxes.Double0Box));
- public double VerticalOffset
- {
- get => (double) GetValue(VerticalOffsetProperty);
- set => SetValue(VerticalOffsetProperty, value);
- }
- public static Magnifier Default => new();
- public static readonly DependencyProperty ScaleProperty = DependencyProperty.Register(
- nameof(Scale), typeof(double), typeof(Magnifier), new PropertyMetadata(5.0, OnScaleChanged), ValidateHelper.IsInRangeOfPosDouble);
- private static void OnScaleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => ((Magnifier) d).UpdateViewboxSize();
- public double Scale
- {
- get => (double) GetValue(ScaleProperty);
- set => SetValue(ScaleProperty, value);
- }
- public Magnifier()
- {
- _translateTransform = new TranslateTransform();
- RenderTransform = _translateTransform;
- }
- public override void OnApplyTemplate()
- {
- base.OnApplyTemplate();
- var visualBrush = GetTemplateChild(ElementVisualBrush) as VisualBrush ?? new VisualBrush();
- visualBrush.Viewbox = _visualBrush.Viewbox;
- _visualBrush = visualBrush;
- }
- protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
- {
- base.OnRenderSizeChanged(sizeInfo);
- UpdateViewboxSize();
- }
- private void UpdateViewboxSize() => _viewboxSize = new Size(ActualWidth / Scale, ActualHeight / Scale);
- protected sealed override void OnTargetChanged(FrameworkElement element, bool isNew)
- {
- base.OnTargetChanged(element, isNew);
- if (element == null) return;
- if (!isNew)
- {
- element.MouseEnter -= Element_MouseEnter;
- element.MouseLeave -= Element_MouseLeave;
- element.MouseMove -= Element_MouseMove;
- ElementTarget = null;
- }
- else
- {
- element.MouseEnter += Element_MouseEnter;
- element.MouseLeave += Element_MouseLeave;
- element.MouseMove += Element_MouseMove;
- ElementTarget = element;
- }
- }
- protected override void Dispose() => HideAdornerElement();
- private void UpdateLocation()
- {
- var targetPoint = Mouse.GetPosition(Target);
- var subX = targetPoint.X - _visualBrush.Viewbox.Width / 2;
- var subY = targetPoint.Y - _visualBrush.Viewbox.Height / 2;
- var targetVector = VisualTreeHelper.GetOffset(Target);
- _visualBrush.Viewbox = new Rect(new Point(subX + targetVector.X, subY + targetVector.Y), _viewboxSize);
- var adornerPoint = Mouse.GetPosition(_adornerContainer);
- _translateTransform.X = adornerPoint.X + HorizontalOffset;
- _translateTransform.Y = adornerPoint.Y + VerticalOffset;
- }
- private void Element_MouseMove(object sender, MouseEventArgs e) => UpdateLocation();
- private void Element_MouseLeave(object sender, MouseEventArgs e) => HideAdornerElement();
- private void Element_MouseEnter(object sender, MouseEventArgs e) => ShowAdornerElement();
- private void HideAdornerElement()
- {
- if (_adornerContainer == null) return;
- var layer = AdornerLayer.GetAdornerLayer(Target);
- if (layer != null)
- {
- layer.Remove(_adornerContainer);
- }
- else if (_adornerContainer is { Parent: AdornerLayer parent })
- {
- parent.Remove(_adornerContainer);
- }
- if (_adornerContainer != null)
- {
- _adornerContainer.Child = null;
- _adornerContainer = null;
- }
- }
- private void ShowAdornerElement()
- {
- if (_adornerContainer == null)
- {
- var layer = AdornerLayer.GetAdornerLayer(Target);
- if (layer == null) return;
- _adornerContainer = new AdornerContainer(layer)
- {
- Child = this
- };
- layer.Add(_adornerContainer);
- }
- this.Show();
- }
- }
|