【问题标题】:How to implement window resizing from all sides using an adorner?如何使用装饰器从各个方向调整窗口大小?
【发布时间】:2017-04-13 04:23:20
【问题描述】:

我有一个无边框透明 wpf 窗口 (WindowStyle=None),我希望能够从各个方面调整大小。如果我设置 ResizeMode=CanResizeWithGrip,当前调整大小仅适用于上述设置。这对视觉提示很好,但不是很好,因为您只能从一个角落调整大小。

我想用一个装饰器来做这个,所以当窗口处于调整大小模式(可以打开和关闭)时,我也可以提供视觉提示。这可能吗?如果是这样,我将如何处理?

【问题讨论】:

    标签: wpf window-resize adorner adornerlayer


    【解决方案1】:

    这个问题已经在 stackoverflow 的某个地方得到了回答。我现在真的找不到它,但我是这样做的。

    主窗口:

    <Window x:Class="Solution.Views.Main.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" MinWidth="1000" MinHeight="500" WindowStyle="None" AllowsTransparency="False" BorderThickness="0" ResizeMode="NoResize">
    
       <Window.TaskbarItemInfo>
         <TaskbarItemInfo />
       </Window.TaskbarItemInfo>
    
      <Grid>
    
        <Border MouseLeftButtonDown="WindowResizeEast" MouseEnter="BorderVertical_OnMouseEnter" MouseLeave="BorderAll_OnMouseLeave" VerticalAlignment="Stretch" HorizontalAlignment="Right" Width="1" Background="Black"/>
        <Border MouseLeftButtonDown="WindowResizeWest" MouseEnter="BorderVertical_OnMouseEnter" MouseLeave="BorderAll_OnMouseLeave"  VerticalAlignment="Stretch" HorizontalAlignment="Left" Width="1" Background="Black"/>
        <Border MouseLeftButtonDown="WindowResizeNorth" MouseEnter="BorderHorizontal_OnMouseEnter" MouseLeave="BorderAll_OnMouseLeave"  VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="1" Background="Black"/>
        <Border MouseLeftButtonDown="WindowResizeSouth" MouseEnter="BorderHorizontal_OnMouseEnter" MouseLeave="BorderAll_OnMouseLeave"  VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Height="1" Background="Black"/>
        <Border VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="20" Height="20" MouseEnter="BorderSouthEast_OnMouseEnter" MouseLeave="BorderAll_OnMouseLeave" MouseLeftButtonDown="UIElement_OnMouseLeftButtonDown">
            <Grid>
                <Path Stroke="Gray" StrokeThickness="1" Data=" M 5 20 L 20 5 M 10 20 L 20 10 M 15 20 L 20 15"/>
            </Grid>
        </Border>
      </Grid>
    </Window>
    

    主窗口代码:

    using System;
    using System.Diagnostics;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Interop;
    using System.Windows.Media;
    using PrmWpf.Services;
    
     public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
    
        [DllImportAttribute("user32.dll")]
        public static extern bool ReleaseCapture();
    
        private void WindowResizeNorth(object sender, MouseButtonEventArgs e) //PreviewMousLeftButtonDown
        {
            var hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
            SendMessage(hwndSource.Handle, 0x112, (IntPtr)ResizeDirection.Top, IntPtr.Zero);
        }
    
        private void WindowResizeSouth(object sender, MouseButtonEventArgs e) //PreviewMousLeftButtonDown
        {
            var hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
            SendMessage(hwndSource.Handle, 0x112, (IntPtr)ResizeDirection.Bottom, IntPtr.Zero);
        }
    
        private void WindowResizeWest(object sender, MouseButtonEventArgs e) //PreviewMousLeftButtonDown
        {
            var hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
            SendMessage(hwndSource.Handle, 0x112, (IntPtr)ResizeDirection.Left, IntPtr.Zero);
        }
    
        private void WindowResizeEast(object sender, MouseButtonEventArgs e) //PreviewMousLeftButtonDown
        {
            var hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
            SendMessage(hwndSource.Handle, 0x112, (IntPtr)ResizeDirection.Right, IntPtr.Zero);
        }
    
        private enum ResizeDirection { Left = 61441, Right = 61442, Top = 61443, Bottom = 61446, BottomRight = 61448, }
    
        private void BorderVertical_OnMouseEnter(object sender, MouseEventArgs e)
        {
            Mouse.OverrideCursor = Cursors.SizeWE;
        }
    
        private void BorderHorizontal_OnMouseEnter(object sender, MouseEventArgs e)
        {
            Mouse.OverrideCursor = Cursors.SizeNS;
        }
    
        private void BorderAll_OnMouseLeave(object sender, MouseEventArgs e)
        {
            Mouse.OverrideCursor = Cursors.Arrow;
        }
    
        private void BorderSouthEast_OnMouseEnter(object sender, MouseEventArgs e)
        {
            Mouse.OverrideCursor = Cursors.SizeNWSE;
        }
    
        private void UIElement_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
            SendMessage(hwndSource.Handle, 0x112, (IntPtr)ResizeDirection.BottomRight, IntPtr.Zero);
        }
    }
    

    【讨论】:

    • 我想当时没有很好的方法可以用装饰器做到这一点。我几乎让它工作了,但调整大小并不是我所期望的。不过,这是一个不错且简单的解决方案。
    • 嗨,@Nawed Nabi Zada。代码 private enum ResizeDirection { Left = 61441, Right = 61442, Top = 61443, Bottom = 61446, BottomRight = 61448, } 是根据什么设置对应的数字?和这个话题有什么关系,是否属于屏幕分辨率和宽度。我该如何根据自己的情况给出这些值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-06
    • 2012-07-02
    • 2011-02-25
    • 2015-06-28
    • 1970-01-01
    • 2021-09-20
    • 1970-01-01
    相关资源
    最近更新 更多