diff --git a/HandyControl/Controls/Attach/WindowAttach.cs b/HandyControl/Controls/Attach/WindowAttach.cs new file mode 100644 index 00000000..99909ec9 --- /dev/null +++ b/HandyControl/Controls/Attach/WindowAttach.cs @@ -0,0 +1,41 @@ +using System.Windows; +using System.Windows.Input; +using HandyControl.Data; + +namespace HandyControl.Controls +{ + public static class WindowAttach + { + public static readonly DependencyProperty IsDragElementProperty = DependencyProperty.RegisterAttached( + "IsDragElement", typeof(bool), typeof(WindowAttach), new PropertyMetadata(ValueBoxes.FalseBox, OnIsDragElementChanged)); + + public static void SetIsDragElement(DependencyObject element, bool value) + => element.SetValue(IsDragElementProperty, value); + + public static bool GetIsDragElement(DependencyObject element) + => (bool) element.GetValue(IsDragElementProperty); + + private static void OnIsDragElementChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is UIElement ctl) + { + if ((bool)e.NewValue) + { + ctl.MouseLeftButtonDown += DragElement_MouseLeftButtonDown; ; + } + else + { + ctl.MouseLeftButtonDown -= DragElement_MouseLeftButtonDown; + } + } + } + + private static void DragElement_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) + { + if (sender is DependencyObject obj && e.ButtonState == MouseButtonState.Pressed) + { + System.Windows.Window.GetWindow(obj)?.DragMove(); + } + } + } +} \ No newline at end of file diff --git a/HandyControl/Controls/Window/Window.cs b/HandyControl/Controls/Window/Window.cs index daa24f1a..ee8d9fc1 100644 --- a/HandyControl/Controls/Window/Window.cs +++ b/HandyControl/Controls/Window/Window.cs @@ -6,17 +6,20 @@ using System.Windows.Input; using System.Windows.Media; using HandyControl.Data; using HandyControl.Tools; +using HandyControl.Tools.Extension; #if netle40 using Microsoft.Windows.Shell; #else using System.Windows.Shell; + #endif namespace HandyControl.Controls { + [TemplatePart(Name = ElementNonClientArea, Type = typeof(UIElement))] public class Window : System.Windows.Window { - private Thickness _tempThickness; + private const string ElementNonClientArea = "PART_NonClientArea"; public static readonly DependencyProperty NonClientAreaContentProperty = DependencyProperty.Register( "NonClientAreaContent", typeof(object), typeof(Window), new PropertyMetadata(default(object))); @@ -66,42 +69,38 @@ namespace HandyControl.Controls new PropertyMetadata(28.0)); public static readonly DependencyProperty ShowNonClientAreaProperty = DependencyProperty.Register( - "ShowNonClientArea", typeof(bool), typeof(Window), new PropertyMetadata(ValueBoxes.TrueBox)); + "ShowNonClientArea", typeof(bool), typeof(Window), + new PropertyMetadata(ValueBoxes.TrueBox, OnShowNonClientAreaChanged)); public static readonly DependencyProperty ShowTitleProperty = DependencyProperty.Register( "ShowTitle", typeof(bool), typeof(Window), new PropertyMetadata(ValueBoxes.FalseBox)); public static readonly DependencyProperty IsFullScreenProperty = DependencyProperty.Register( - "IsFullScreen", typeof(bool), typeof(Window), new PropertyMetadata(ValueBoxes.FalseBox, - (o, args) => - { - var ctl = (Window)o; - var v = (bool)args.NewValue; - if (v) - { - ctl.OriginState = ctl.WindowState; - ctl.OriginStyle = ctl.WindowStyle; - ctl.OriginResizeMode = ctl.ResizeMode; - ctl.WindowStyle = WindowStyle.None; - //下面三行不能改变,就是故意的 - ctl.WindowState = WindowState.Maximized; - ctl.WindowState = WindowState.Minimized; - ctl.WindowState = WindowState.Maximized; - } - else - { - ctl.WindowState = ctl.OriginState; - ctl.WindowStyle = ctl.OriginStyle; - ctl.ResizeMode = ctl.OriginResizeMode; - } - })); + "IsFullScreen", typeof(bool), typeof(Window), + new PropertyMetadata(ValueBoxes.FalseBox, OnIsFullScreenChanged)); + + private bool _isFullScreen; + + private UIElement _nonClientArea; + + private bool _showNonClientArea = true; + + private double _tempNonClientAreaHeight; + + private Thickness _tempThickness; + + private WindowState _tempWindowState; + + private WindowStyle _tempWindowStyle; + + private ResizeMode _tempResizeMode; public Window() { var chrome = new WindowChrome { CornerRadius = new CornerRadius(), - GlassFrameThickness = new Thickness(1) + GlassFrameThickness = new Thickness(0, 0, 0, 1) }; BindingOperations.SetBinding(chrome, WindowChrome.CaptionHeightProperty, new Binding(NonClientAreaHeightProperty.Name) {Source = this}); @@ -123,9 +122,192 @@ namespace HandyControl.Controls (s, e) => WindowState = WindowState.Normal)); CommandBindings.Add(new CommandBinding(SystemCommands.CloseWindowCommand, (s, e) => Close())); CommandBindings.Add(new CommandBinding(SystemCommands.ShowSystemMenuCommand, ShowSystemMenu)); + + _tempNonClientAreaHeight = NonClientAreaHeight; + _tempWindowState = WindowState; + _tempWindowStyle = WindowStyle; + _tempResizeMode = ResizeMode; + + SwitchIsFullScreen(_isFullScreen); + SwitchShowNonClientArea(_showNonClientArea); }; } + public Brush CloseButtonBackground + { + get => (Brush) GetValue(CloseButtonBackgroundProperty); + set => SetValue(CloseButtonBackgroundProperty, value); + } + + public Brush CloseButtonForeground + { + get => (Brush) GetValue(CloseButtonForegroundProperty); + set => SetValue(CloseButtonForegroundProperty, value); + } + + public Brush OtherButtonBackground + { + get => (Brush) GetValue(OtherButtonBackgroundProperty); + set => SetValue(OtherButtonBackgroundProperty, value); + } + + public Brush OtherButtonForeground + { + get => (Brush) GetValue(OtherButtonForegroundProperty); + set => SetValue(OtherButtonForegroundProperty, value); + } + + public double NonClientAreaHeight + { + get => (double) GetValue(NonClientAreaHeightProperty); + set => SetValue(NonClientAreaHeightProperty, value); + } + + public bool IsFullScreen + { + get => (bool) GetValue(IsFullScreenProperty); + set => SetValue(IsFullScreenProperty, value); + } + + public object NonClientAreaContent + { + get => GetValue(NonClientAreaContentProperty); + set => SetValue(NonClientAreaContentProperty, value); + } + + public Brush CloseButtonHoverBackground + { + get => (Brush) GetValue(CloseButtonHoverBackgroundProperty); + set => SetValue(CloseButtonHoverBackgroundProperty, value); + } + + public Brush CloseButtonHoverForeground + { + get => (Brush) GetValue(CloseButtonHoverForegroundProperty); + set => SetValue(CloseButtonHoverForegroundProperty, value); + } + + public Brush OtherButtonHoverBackground + { + get => (Brush) GetValue(OtherButtonHoverBackgroundProperty); + set => SetValue(OtherButtonHoverBackgroundProperty, value); + } + + public Brush OtherButtonHoverForeground + { + get => (Brush) GetValue(OtherButtonHoverForegroundProperty); + set => SetValue(OtherButtonHoverForegroundProperty, value); + } + + public Brush NonClientAreaBackground + { + get => (Brush) GetValue(NonClientAreaBackgroundProperty); + set => SetValue(NonClientAreaBackgroundProperty, value); + } + + public Brush NonClientAreaForeground + { + get => (Brush) GetValue(NonClientAreaForegroundProperty); + set => SetValue(NonClientAreaForegroundProperty, value); + } + + public bool ShowNonClientArea + { + get => (bool) GetValue(ShowNonClientAreaProperty); + set => SetValue(ShowNonClientAreaProperty, value); + } + + public bool ShowTitle + { + get => (bool) GetValue(ShowTitleProperty); + set => SetValue(ShowTitleProperty, value); + } + + private static void OnShowNonClientAreaChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var ctl = (Window) d; + ctl.SwitchShowNonClientArea((bool) e.NewValue); + } + + private void SwitchShowNonClientArea(bool showNonClientArea) + { + if (_nonClientArea == null) + { + _showNonClientArea = showNonClientArea; + return; + } + + if (showNonClientArea) + { + if (IsFullScreen) + { + _nonClientArea.Show(false); + _tempNonClientAreaHeight = NonClientAreaHeight; + NonClientAreaHeight = 0; + } + else + { + _nonClientArea.Show(true); + NonClientAreaHeight = _tempNonClientAreaHeight; + } + } + else + { + _nonClientArea.Show(false); + _tempNonClientAreaHeight = NonClientAreaHeight; + NonClientAreaHeight = 0; + } + } + + private static void OnIsFullScreenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var ctl = (Window) d; + ctl.SwitchIsFullScreen((bool) e.NewValue); + } + + private void SwitchIsFullScreen(bool isFullScreen) + { + if (_nonClientArea == null) + { + _isFullScreen = isFullScreen; + return; + } + + if (isFullScreen) + { + _nonClientArea.Show(false); + _tempNonClientAreaHeight = NonClientAreaHeight; + NonClientAreaHeight = 0; + + _tempWindowState = WindowState; + _tempWindowStyle = WindowStyle; + _tempResizeMode = ResizeMode; + WindowStyle = WindowStyle.None; + //下面三行不能改变,就是故意的 + WindowState = WindowState.Maximized; + WindowState = WindowState.Minimized; + WindowState = WindowState.Maximized; + } + else + { + if (ShowNonClientArea) + { + _nonClientArea.Show(true); + NonClientAreaHeight = _tempNonClientAreaHeight; + } + else + { + _nonClientArea.Show(false); + _tempNonClientAreaHeight = NonClientAreaHeight; + NonClientAreaHeight = 0; + } + + WindowState = _tempWindowState; + WindowStyle = _tempWindowStyle; + ResizeMode = _tempResizeMode; + } + } + protected override void OnStateChanged(EventArgs e) { base.OnStateChanged(e); @@ -143,6 +325,8 @@ namespace HandyControl.Controls { base.OnApplyTemplate(); + _nonClientArea = GetTemplateChild(ElementNonClientArea) as UIElement; + if (SizeToContent != SizeToContent.WidthAndHeight) return; @@ -150,111 +334,6 @@ namespace HandyControl.Controls Dispatcher.BeginInvoke(new Action(() => { SizeToContent = SizeToContent.WidthAndHeight; })); } - public Brush CloseButtonBackground - { - get => (Brush)GetValue(CloseButtonBackgroundProperty); - set => SetValue(CloseButtonBackgroundProperty, value); - } - - public Brush CloseButtonForeground - { - get => (Brush)GetValue(CloseButtonForegroundProperty); - set => SetValue(CloseButtonForegroundProperty, value); - } - - public Brush OtherButtonBackground - { - get => (Brush)GetValue(OtherButtonBackgroundProperty); - set => SetValue(OtherButtonBackgroundProperty, value); - } - - public Brush OtherButtonForeground - { - get => (Brush)GetValue(OtherButtonForegroundProperty); - set => SetValue(OtherButtonForegroundProperty, value); - } - - /// - /// 原始状态 - /// - private WindowState OriginState { get; set; } - - /// - /// 原始样式 - /// - private WindowStyle OriginStyle { get; set; } - - /// - /// 原始尺寸调节模式 - /// - private ResizeMode OriginResizeMode { get; set; } - - public double NonClientAreaHeight - { - get => (double)GetValue(NonClientAreaHeightProperty); - set => SetValue(NonClientAreaHeightProperty, value); - } - - public bool IsFullScreen - { - get => (bool)GetValue(IsFullScreenProperty); - set => SetValue(IsFullScreenProperty, value); - } - - public object NonClientAreaContent - { - get => GetValue(NonClientAreaContentProperty); - set => SetValue(NonClientAreaContentProperty, value); - } - - public Brush CloseButtonHoverBackground - { - get => (Brush)GetValue(CloseButtonHoverBackgroundProperty); - set => SetValue(CloseButtonHoverBackgroundProperty, value); - } - - public Brush CloseButtonHoverForeground - { - get => (Brush)GetValue(CloseButtonHoverForegroundProperty); - set => SetValue(CloseButtonHoverForegroundProperty, value); - } - - public Brush OtherButtonHoverBackground - { - get => (Brush)GetValue(OtherButtonHoverBackgroundProperty); - set => SetValue(OtherButtonHoverBackgroundProperty, value); - } - - public Brush OtherButtonHoverForeground - { - get => (Brush)GetValue(OtherButtonHoverForegroundProperty); - set => SetValue(OtherButtonHoverForegroundProperty, value); - } - - public Brush NonClientAreaBackground - { - get => (Brush)GetValue(NonClientAreaBackgroundProperty); - set => SetValue(NonClientAreaBackgroundProperty, value); - } - - public Brush NonClientAreaForeground - { - get => (Brush)GetValue(NonClientAreaForegroundProperty); - set => SetValue(NonClientAreaForegroundProperty, value); - } - - public bool ShowNonClientArea - { - get => (bool)GetValue(ShowNonClientAreaProperty); - set => SetValue(ShowNonClientAreaProperty, value); - } - - public bool ShowTitle - { - get => (bool)GetValue(ShowTitleProperty); - set => SetValue(ShowTitleProperty, value); - } - private void ShowSystemMenu(object sender, ExecutedRoutedEventArgs e) { var point = WindowState == WindowState.Maximized diff --git a/HandyControl/HandyControl.csproj b/HandyControl/HandyControl.csproj index 77f6eba7..102d35b2 100644 --- a/HandyControl/HandyControl.csproj +++ b/HandyControl/HandyControl.csproj @@ -114,6 +114,7 @@ + diff --git a/HandyControl/Properties/Langs/Lang.en.resx b/HandyControl/Properties/Langs/Lang.en.resx index 162027ec..ee8c3009 100644 --- a/HandyControl/Properties/Langs/Lang.en.resx +++ b/HandyControl/Properties/Langs/Lang.en.resx @@ -53,7 +53,6 @@ value : The object must be serialized with : System.Runtime.Serialization.Formatters.Soap.SoapFormatter : and then encoded with base64 encoding. - mimetype: application/x-microsoft.net.object.bytearray.base64 value : The object must be serialized into a byte array : using a System.ComponentModel.TypeConverter diff --git a/HandyControl/Themes/Styles/Window-net40.tt b/HandyControl/Themes/Styles/Window-net40.tt index 0547b26d..4c0aec27 100644 --- a/HandyControl/Themes/Styles/Window-net40.tt +++ b/HandyControl/Themes/Styles/Window-net40.tt @@ -40,16 +40,16 @@ - + -