optimize<Adorner>: move adorner management to Controls.Window

This commit is contained in:
leo 2021-08-06 17:19:04 +08:00
parent 84a0e9f463
commit 580ff565d8
4 changed files with 60 additions and 49 deletions

View file

@ -19,10 +19,20 @@
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="WindowState" Value="Maximized">
<Setter Property="BorderThickness" Value="0"/>
</Trigger>
</Style.Triggers>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<AdornerDecorator>
<Border
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}">
<ContentPresenter/>
</Border>
</AdornerDecorator>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View file

@ -1,39 +1,9 @@
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
namespace SourceGit.Views.Controls {
/// <summary>
/// DragDropAdorner容器
/// </summary>
public class DragDropAdornerLayer : Grid {
private static AdornerLayer host = null;
private static bool enableFeedback = false;
public DragDropAdornerLayer() {
Loaded += (o, e) => host = AdornerLayer.GetAdornerLayer(this);
PreviewGiveFeedback += OnPreviewGiveFeedback;
}
public static void Add(Adorner adorner) {
host.Add(adorner);
enableFeedback = true;
}
public static void Remove(Adorner adorner) {
host.Remove(adorner);
enableFeedback = false;
}
private static void OnPreviewGiveFeedback(object sender, GiveFeedbackEventArgs e) {
if (enableFeedback) host.Update();
e.Handled = true;
}
}
/// <summary>
/// 展示正在拖拽的视图
/// </summary>
@ -56,11 +26,11 @@ namespace SourceGit.Views.Controls {
renderSize = elem.RenderSize;
renderBrush = new VisualBrush(elem);
IsHitTestVisible = false;
DragDropAdornerLayer.Add(this);
Window.AddAdorner(elem, this);
}
public void Remove() {
DragDropAdornerLayer.Remove(this);
Window.RemoveAdorner(this);
}
protected override void OnRender(DrawingContext dc) {
@ -73,6 +43,7 @@ namespace SourceGit.Views.Controls {
Rect rect = new Rect(pos.X, pos.Y, renderSize.Width, renderSize.Height);
dc.PushOpacity(1);
dc.DrawRectangle(FindResource("Brush.Window") as Brush, null, rect);
dc.DrawRectangle(renderBrush, null, rect);
dc.DrawRectangle(null, new Pen(Brushes.DeepSkyBlue, 2), rect);
}

View file

@ -1,4 +1,7 @@
using System;
using System.Windows;
using System.Windows.Documents;
using System.Collections.Generic;
namespace SourceGit.Views.Controls {
/// <summary>
@ -17,20 +20,47 @@ namespace SourceGit.Views.Controls {
set { SetValue(IsMaximizedProperty, value); }
}
private AdornerLayer adornerLayer = null;
private List<Adorner> adorners = new List<Adorner>();
public Window() {
Style = FindResource("Style.Window") as Style;
Loaded += (_, __) => adornerLayer = AdornerLayer.GetAdornerLayer(Content as FrameworkElement);
}
StateChanged += (_, __) => {
var content = Content as FrameworkElement;
public static void AddAdorner(FrameworkElement elem, Adorner adorner) {
var wnd = GetWindow(elem) as Window;
if (wnd != null && wnd.adornerLayer != null) {
wnd.adorners.Add(adorner);
wnd.adornerLayer.Add(adorner);
}
}
if (WindowState == WindowState.Maximized) {
if (!IsMaximized) IsMaximized = true;
content.Margin = new Thickness((SystemParameters.MaximizedPrimaryScreenWidth - SystemParameters.WorkArea.Width) / 2);
} else {
if (IsMaximized) IsMaximized = false;
content.Margin = new Thickness(0);
}
};
public static void RemoveAdorner(Adorner adorner) {
var wnd = GetWindow(adorner) as Window;
if (wnd != null && wnd.adornerLayer != null) {
wnd.adorners.Remove(adorner);
wnd.adornerLayer.Remove(adorner);
}
}
protected override void OnPreviewGiveFeedback(GiveFeedbackEventArgs e) {
base.OnPreviewGiveFeedback(e);
if (adornerLayer != null && adorners.Count > 0) adornerLayer.Update();
}
protected override void OnStateChanged(EventArgs e) {
base.OnStateChanged(e);
if (WindowState == WindowState.Maximized) {
if (!IsMaximized) IsMaximized = true;
BorderThickness = new Thickness(0);
Padding = new Thickness((SystemParameters.MaximizedPrimaryScreenWidth - SystemParameters.WorkArea.Width) / 2);
} else {
if (IsMaximized) IsMaximized = false;
BorderThickness = new Thickness(1);
Padding = new Thickness(0);
}
}
private static void OnIsMaximizedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {

View file

@ -15,7 +15,7 @@
Width="{Binding Source={x:Static models:Preference.Instance}, Path=Window.Width, Mode=TwoWay}"
Height="{Binding Source={x:Static models:Preference.Instance}, Path=Window.Height, Mode=TwoWay}"
Closing="OnClosing">
<controls:DragDropAdornerLayer>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="28"/>
<RowDefinition Height="*"/>
@ -61,5 +61,5 @@
Grid.Row="1"
HorizontalAlignment="Right" VerticalAlignment="Top"
Width="330" Height="Auto"/>
</controls:DragDropAdornerLayer>
</Grid>
</controls:Window>