refactor Poptip & Magnifier
This commit is contained in:
1 parent
6fd86496a2
commit
d0dc957c81
4 files changed
+134
-104
No files matched your search
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using HandyControl.Data;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
public abstract class AdornerElement : Control, IDisposable
|
||||
{
|
||||
protected FrameworkElement ElementTarget { get; set; }
|
||||
|
||||
public static readonly DependencyProperty TargetProperty = DependencyProperty.Register(
|
||||
"Target", typeof(FrameworkElement), typeof(AdornerElement), new PropertyMetadata(default(FrameworkElement), OnTargetChanged));
|
||||
|
||||
private static void OnTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var ctl = (AdornerElement)d;
|
||||
ctl.OnTargetChanged(ctl.ElementTarget, false);
|
||||
ctl.OnTargetChanged((FrameworkElement)e.NewValue, true);
|
||||
}
|
||||
|
||||
[Bindable(true), Category("Layout")]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public FrameworkElement Target
|
||||
{
|
||||
get => (FrameworkElement) GetValue(TargetProperty);
|
||||
set => SetValue(TargetProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty InstanceProperty = DependencyProperty.RegisterAttached(
|
||||
"Instance", typeof(AdornerElement), typeof(AdornerElement), new PropertyMetadata(default(AdornerElement), OnInstanceChanged));
|
||||
|
||||
private static void OnInstanceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (!(d is FrameworkElement target)) return;
|
||||
var element = (AdornerElement)e.NewValue;
|
||||
element.OnInstanceChanged(target);
|
||||
}
|
||||
|
||||
protected virtual void OnInstanceChanged(FrameworkElement target) => Target = target;
|
||||
|
||||
public static void SetInstance(DependencyObject element, AdornerElement value)
|
||||
=> element.SetValue(InstanceProperty, value);
|
||||
|
||||
public static AdornerElement GetInstance(DependencyObject element)
|
||||
=> (AdornerElement) element.GetValue(InstanceProperty);
|
||||
|
||||
public static readonly DependencyProperty IsInstanceProperty = DependencyProperty.RegisterAttached(
|
||||
"IsInstance", typeof(bool), typeof(AdornerElement), new PropertyMetadata(ValueBoxes.TrueBox));
|
||||
|
||||
public static void SetIsInstance(DependencyObject element, bool value)
|
||||
=> element.SetValue(IsInstanceProperty, value);
|
||||
|
||||
public static bool GetIsInstance(DependencyObject element)
|
||||
=> (bool) element.GetValue(IsInstanceProperty);
|
||||
|
||||
protected virtual void OnTargetChanged(FrameworkElement element, bool isNew)
|
||||
{
|
||||
if (element == null) return;
|
||||
|
||||
if (!isNew)
|
||||
{
|
||||
element.Unloaded -= TargetElement_Unloaded;
|
||||
ElementTarget = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
element.Unloaded += TargetElement_Unloaded;
|
||||
ElementTarget = element;
|
||||
}
|
||||
}
|
||||
|
||||
private void TargetElement_Unloaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is FrameworkElement element)
|
||||
{
|
||||
element.Unloaded -= TargetElement_Unloaded;
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void Dispose();
|
||||
|
||||
void IDisposable.Dispose() => Dispose();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
@@ -11,14 +10,12 @@ using HandyControl.Tools.Extension;
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
[TemplatePart(Name = ElementVisualBrush, Type = typeof(VisualBrush))]
|
||||
public class Magnifier : Control
|
||||
public class Magnifier : AdornerElement
|
||||
{
|
||||
private AdornerContainer _adornerContainer;
|
||||
|
||||
private Size _viewboxSize;
|
||||
|
||||
private AdornerContainer _adorner;
|
||||
|
||||
private UIElement _elementTarget;
|
||||
|
||||
private const string ElementVisualBrush = "PART_VisualBrush";
|
||||
|
||||
private VisualBrush _visualBrush = new VisualBrush();
|
||||
@@ -43,40 +40,8 @@ namespace HandyControl.Controls
|
||||
set => SetValue(VerticalOffsetProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty InstanceProperty = DependencyProperty.RegisterAttached(
|
||||
"Instance", typeof(Magnifier), typeof(Magnifier), new PropertyMetadata(default(Magnifier), OnMagnifierChanged));
|
||||
|
||||
private static void OnMagnifierChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (!(d is UIElement target)) return;
|
||||
var magnifier = (Magnifier)e.NewValue;
|
||||
magnifier.Target = target;
|
||||
}
|
||||
|
||||
public static void SetInstance(DependencyObject element, Magnifier value)
|
||||
=> element.SetValue(InstanceProperty, value);
|
||||
|
||||
public static Magnifier GetInstance(DependencyObject element)
|
||||
=> (Magnifier) element.GetValue(InstanceProperty);
|
||||
|
||||
public static Magnifier Default => new Magnifier();
|
||||
|
||||
internal static readonly DependencyProperty TargetProperty = DependencyProperty.Register(
|
||||
"Target", typeof(UIElement), typeof(Magnifier), new PropertyMetadata(default(UIElement), OnTargetChanged));
|
||||
|
||||
private static void OnTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var ctl = (Magnifier) d;
|
||||
ctl.UpdateTarget(ctl._elementTarget, false);
|
||||
ctl.UpdateTarget((UIElement)e.NewValue, true);
|
||||
}
|
||||
|
||||
internal UIElement Target
|
||||
{
|
||||
get => (UIElement)GetValue(TargetProperty);
|
||||
set => SetValue(TargetProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty ScaleProperty = DependencyProperty.Register(
|
||||
"Scale", typeof(double), typeof(Magnifier), new PropertyMetadata(5.0, OnScaleChanged), ValidateHelper.IsInRangeOfPosDouble);
|
||||
|
||||
@@ -111,8 +76,10 @@ namespace HandyControl.Controls
|
||||
|
||||
private void UpdateViewboxSize() => _viewboxSize = new Size(ActualWidth / Scale, ActualHeight / Scale);
|
||||
|
||||
private void UpdateTarget(UIElement element , bool isNew)
|
||||
protected sealed override void OnTargetChanged(FrameworkElement element , bool isNew)
|
||||
{
|
||||
base.OnTargetChanged(element, isNew);
|
||||
|
||||
if (element == null) return;
|
||||
|
||||
if (!isNew)
|
||||
@@ -120,17 +87,19 @@ namespace HandyControl.Controls
|
||||
element.MouseEnter -= Element_MouseEnter;
|
||||
element.MouseLeave -= Element_MouseLeave;
|
||||
element.MouseMove -= Element_MouseMove;
|
||||
_elementTarget = null;
|
||||
ElementTarget = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
element.MouseEnter += Element_MouseEnter;
|
||||
element.MouseLeave += Element_MouseLeave;
|
||||
element.MouseMove += Element_MouseMove;
|
||||
_elementTarget = element;
|
||||
ElementTarget = element;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose() => HideAdornerElement();
|
||||
|
||||
private void UpdateLocation()
|
||||
{
|
||||
var targetPoint = Mouse.GetPosition(Target);
|
||||
@@ -140,33 +109,48 @@ namespace HandyControl.Controls
|
||||
var targetVector = VisualTreeHelper.GetOffset(Target);
|
||||
_visualBrush.Viewbox = new Rect(new Point(subX + targetVector.X, subY + targetVector.Y), _viewboxSize);
|
||||
|
||||
var adornerPoint = Mouse.GetPosition(_adorner);
|
||||
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)
|
||||
private void Element_MouseLeave(object sender, MouseEventArgs e) => HideAdornerElement();
|
||||
|
||||
private void Element_MouseEnter(object sender, MouseEventArgs e) => ShowAdornerElement();
|
||||
|
||||
private void HideAdornerElement()
|
||||
{
|
||||
var layer = AdornerLayer.GetAdornerLayer(Target);
|
||||
if (layer == null) return;
|
||||
layer.Remove(_adorner);
|
||||
_adorner.Child = null;
|
||||
_adorner = null;
|
||||
if (layer != null)
|
||||
{
|
||||
layer.Remove(_adornerContainer);
|
||||
}
|
||||
else if(_adornerContainer != null && _adornerContainer.Parent is AdornerLayer parent)
|
||||
{
|
||||
parent.Remove(_adornerContainer);
|
||||
}
|
||||
|
||||
if (_adornerContainer != null)
|
||||
{
|
||||
_adornerContainer.Child = null;
|
||||
_adornerContainer = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void Element_MouseEnter(object sender, MouseEventArgs e)
|
||||
private void ShowAdornerElement()
|
||||
{
|
||||
if (_adorner == null)
|
||||
if (_adornerContainer == null)
|
||||
{
|
||||
var layer = AdornerLayer.GetAdornerLayer(Target);
|
||||
if (layer == null) return;
|
||||
_adorner = new AdornerContainer(layer)
|
||||
|
||||
_adornerContainer = new AdornerContainer(layer)
|
||||
{
|
||||
Child = this
|
||||
};
|
||||
layer.Add(_adorner);
|
||||
layer.Add(_adornerContainer);
|
||||
}
|
||||
this.Show();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
@@ -10,12 +9,10 @@ using HandyControl.Data.Enum;
|
||||
|
||||
namespace HandyControl.Controls
|
||||
{
|
||||
public class Poptip : Control
|
||||
public class Poptip : AdornerElement
|
||||
{
|
||||
private readonly Popup _popup;
|
||||
|
||||
private UIElement _elementTarget;
|
||||
|
||||
public Poptip()
|
||||
{
|
||||
_popup = new Popup
|
||||
@@ -42,15 +39,6 @@ namespace HandyControl.Controls
|
||||
set => SetValue(HitModeProperty, value);
|
||||
}
|
||||
|
||||
private static readonly DependencyProperty IsInstanceProperty = DependencyProperty.RegisterAttached(
|
||||
"IsInstance", typeof(bool), typeof(Poptip), new PropertyMetadata(ValueBoxes.TrueBox));
|
||||
|
||||
private static void SetIsInstance(DependencyObject element, bool value)
|
||||
=> element.SetValue(IsInstanceProperty, value);
|
||||
|
||||
private static bool GetIsInstance(DependencyObject element)
|
||||
=> (bool) element.GetValue(IsInstanceProperty);
|
||||
|
||||
public static readonly DependencyProperty ContentProperty = DependencyProperty.RegisterAttached(
|
||||
"Content", typeof(object), typeof(Poptip), new PropertyMetadata(default, OnContentChanged));
|
||||
|
||||
@@ -144,7 +132,7 @@ namespace HandyControl.Controls
|
||||
}
|
||||
else
|
||||
{
|
||||
GetInstance(d)?.SwitchPoptip((bool)e.NewValue);
|
||||
((Poptip)GetInstance(d))?.SwitchPoptip((bool)e.NewValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,44 +148,12 @@ namespace HandyControl.Controls
|
||||
set => SetValue(IsOpenProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty TargetProperty = DependencyProperty.Register(
|
||||
"Target", typeof(UIElement), typeof(Poptip), new PropertyMetadata(default(UIElement), OnTargetChanged));
|
||||
|
||||
private static void OnTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var ctl = (Poptip)d;
|
||||
ctl.UpdateTarget(ctl._elementTarget, false);
|
||||
ctl.UpdateTarget((UIElement)e.NewValue, true);
|
||||
}
|
||||
|
||||
[Bindable(true), Category("Layout")]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public UIElement Target
|
||||
{
|
||||
get => (UIElement) GetValue(TargetProperty);
|
||||
set => SetValue(TargetProperty, value);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty InstanceProperty = DependencyProperty.RegisterAttached(
|
||||
"Instance", typeof(Poptip), typeof(Poptip), new PropertyMetadata(default(Poptip), OnPoptipChanged));
|
||||
|
||||
private static void OnPoptipChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (!(d is UIElement target)) return;
|
||||
var poptip = (Poptip)e.NewValue;
|
||||
poptip.Target = target;
|
||||
}
|
||||
|
||||
public static void SetInstance(DependencyObject element, Poptip value)
|
||||
=> element.SetValue(InstanceProperty, value);
|
||||
|
||||
public static Poptip GetInstance(DependencyObject element)
|
||||
=> (Poptip)element.GetValue(InstanceProperty);
|
||||
|
||||
public static Poptip Default => new Poptip();
|
||||
|
||||
private void UpdateTarget(UIElement element, bool isNew)
|
||||
protected sealed override void OnTargetChanged(FrameworkElement element, bool isNew)
|
||||
{
|
||||
base.OnTargetChanged(element, isNew);
|
||||
|
||||
if (element == null) return;
|
||||
|
||||
if (!isNew)
|
||||
@@ -206,7 +162,7 @@ namespace HandyControl.Controls
|
||||
element.MouseLeave -= Element_MouseLeave;
|
||||
element.GotFocus -= Element_GotFocus;
|
||||
element.LostFocus -= Element_LostFocus;
|
||||
_elementTarget = null;
|
||||
ElementTarget = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -214,11 +170,13 @@ namespace HandyControl.Controls
|
||||
element.MouseLeave += Element_MouseLeave;
|
||||
element.GotFocus += Element_GotFocus;
|
||||
element.LostFocus += Element_LostFocus;
|
||||
_elementTarget = element;
|
||||
_popup.PlacementTarget = _elementTarget;
|
||||
ElementTarget = element;
|
||||
_popup.PlacementTarget = ElementTarget;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose() => SwitchPoptip(false);
|
||||
|
||||
private void UpdateLocation()
|
||||
{
|
||||
var targetWidth = Target.RenderSize.Width;
|
||||
@@ -233,7 +191,7 @@ namespace HandyControl.Controls
|
||||
var offsetX = .0;
|
||||
var offsetY = .0;
|
||||
|
||||
var poptip = GetInstance(Target);
|
||||
var poptip = (Poptip)GetInstance(Target);
|
||||
var popupPlacement = poptip.Placement;
|
||||
var popupOffset = poptip.Offset;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Attach\PasswordBoxAttach.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Attach\RectangleAttach.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Attach\TextBlockAttach.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Base\AdornerElement.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Block\FloatingBlock.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Button\SplitButton.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\Growl\GrowlWindow.cs" />
|
||||
|
||||
Reference in new issue
Block a user