Wpf自定义窗口,Windows边缘调整大小功能

时间:2014-11-26 19:29:40

标签: c# wpf windows

有一个自定义的wpf窗口(WindowStyle = None,AllowTransparancy = true)并想知道如何让Windows边缘调整大小功能正常工作..你知道当窗口和鼠标触摸屏幕的左边,右边或顶边时(甚至角落) W10)。

试图调查WM notification,但似乎没有人正在寻找......

要清除,而不是普通的窗口调整大小..但是延伸到屏幕边缘并让Windows将其调整为一半/全部/四分之一(想想它称为Aero Snap)。我可以使用普通的调整大小调用来实现它,但是当触摸边缘时,它不显示透明预览窗口或在鼠标上放置动画。

由于

3 个答案:

答案 0 :(得分:12)

第1步

为矩形创建一个样式(在<Window1.Resources>中)作为窗口周围的Grip区域:

<Style x:Key="RectBorderStyle" TargetType="Rectangle">
    <Setter Property="Focusable" Value="False" />
    <Setter Property="Fill" Value="Transparent" />
    <Setter Property="Tag" Value="{Binding RelativeSource={RelativeSource AncestorType=Window}}" />
    <EventSetter Event="MouseLeftButtonDown" Handler="Resize_Init"/>
    <EventSetter Event="MouseLeftButtonUp" Handler="Resize_End"/>
    <EventSetter Event="MouseMove" Handler="Resizeing_Form"/>
</Style>

第2步

将这些样式的矩形添加到窗口中。 (您可以将它们添加到窗口内的简单网格中)

<Rectangle x:Name="leftSizeGrip"
    Width="7"
    HorizontalAlignment="Left"
    Cursor="SizeWE"
    Style="{StaticResource RectBorderStyle}" />
<Rectangle x:Name="rightSizeGrip"
    Width="7"
    HorizontalAlignment="Right"
    Cursor="SizeWE"
    Style="{StaticResource RectBorderStyle}" />
<Rectangle x:Name="topSizeGrip"
    Height="7"
    VerticalAlignment="Top"
    Cursor="SizeNS"
    Style="{StaticResource RectBorderStyle}" />
<Rectangle x:Name="bottomSizeGrip"
    Height="7"
    VerticalAlignment="Bottom"
    Cursor="SizeNS"
    Style="{StaticResource RectBorderStyle}" />
<!--  Corners  -->
<Rectangle Name="topLeftSizeGrip"
    Width="7"
    Height="7"
    HorizontalAlignment="Left"
    VerticalAlignment="Top"
    Cursor="SizeNWSE"
    Style="{StaticResource RectBorderStyle}" />
<Rectangle Name="bottomRightSizeGrip"
    Width="7"
    Height="7"
    HorizontalAlignment="Right"
    VerticalAlignment="Bottom"
    Cursor="SizeNWSE"
    Style="{StaticResource RectBorderStyle}" />
<Rectangle Name="topRightSizeGrip"
    Width="7"
    Height="7"
    HorizontalAlignment="Right"
    VerticalAlignment="Top"
    Cursor="SizeNESW"
    Style="{StaticResource RectBorderStyle}" />
<Rectangle Name="bottomLeftSizeGrip"
    Width="7"
    Height="7"
    HorizontalAlignment="Left"
    VerticalAlignment="Bottom"
    Cursor="SizeNESW"
    Style="{StaticResource RectBorderStyle}" />

第3步

将这些代码添加到窗口后面的代码(window1.xaml.cs)(如果您使用窗口模板并且在模板中添加了8个矩形,则添加到MyStyle.xaml.cs)

#region ResizeWindows
bool ResizeInProcess = false;
private void Resize_Init(object sender, MouseButtonEventArgs e)
{
    Rectangle senderRect = sender as Rectangle;
    if (senderRect != null)
    {
        ResizeInProcess = true;
        senderRect.CaptureMouse();
    }
}

private void Resize_End(object sender, MouseButtonEventArgs e)
{
    Rectangle senderRect = sender as Rectangle;
    if (senderRect != null)
    {
        ResizeInProcess = false; ;
        senderRect.ReleaseMouseCapture();
    }
}

private void Resizeing_Form(object sender, MouseEventArgs e)
{
    if (ResizeInProcess)
    {
        Rectangle senderRect = sender as Rectangle;
        Window mainWindow = senderRect.Tag as Window;
        if (senderRect != null)
        {
            double width = e.GetPosition(mainWindow).X;
            double height = e.GetPosition(mainWindow).Y;
            senderRect.CaptureMouse();
            if (senderRect.Name.ToLower().Contains("right"))
            {
                width += 5;
                if (width > 0)
                    mainWindow.Width = width;
            }
            if (senderRect.Name.ToLower().Contains("left"))
            {
                width -= 5;
                mainWindow.Left += width;
                width = mainWindow.Width - width;
                if (width > 0)
                {
                    mainWindow.Width = width;
                }
            }
            if (senderRect.Name.ToLower().Contains("bottom"))
            {
                height += 5;
                if (height > 0)
                    mainWindow.Height = height;
            }
            if (senderRect.Name.ToLower().Contains("top"))
            {
                height -= 5;
                mainWindow.Top += height;
                height = mainWindow.Height - height;
                if (height > 0)
                {
                    mainWindow.Height = height;
                }
            }
        }
    }
}
#endregion

第4步

按F5欣赏!

注意:

这8个矩形是透明的。如果您无法正常使用,只需将样式的Fill值更改为Red即可查看它们的位置。

另一个注意事项:

最大化时,您可能想要禁用所有这些矩形。最简单的方法是处理WindowStateChanged事件并禁用包含它们的网格。

答案 1 :(得分:0)

Bizhan的答案太棒了!但是他犯了一个小错误。它的解决方案不考虑最大和最小窗口大小。因此,它会移动而不是更改窗口。工作正常:

    private void Resizeing_Form(object sender, MouseEventArgs e)
    {
        if (ResizeInProcess)
        {
            double temp = 0;
            Rectangle senderRect = sender as Rectangle;
            Window mainWindow = senderRect.Tag as Window;
            if (senderRect != null)
            {
                double width = e.GetPosition(mainWindow).X;
                double height = e.GetPosition(mainWindow).Y;
                senderRect.CaptureMouse();
                if (senderRect.Name.Contains("right", StringComparison.OrdinalIgnoreCase))
                {
                    width += 5;
                    if (width > 0)
                        mainWindow.Width = width;
                }
                if (senderRect.Name.Contains("left", StringComparison.OrdinalIgnoreCase))
                {
                    width -= 5;
                    temp = mainWindow.Width - width;
                    if ((temp > mainWindow.MinWidth) && (temp < mainWindow.MaxWidth))
                    {
                        mainWindow.Width = temp;
                        mainWindow.Left += width;
                    }
                }
                if (senderRect.Name.Contains("bottom", StringComparison.OrdinalIgnoreCase))
                {
                    height += 5;
                    if (height > 0)
                        mainWindow.Height = height;
                }
                if (senderRect.Name.ToLower().Contains("top", StringComparison.OrdinalIgnoreCase))
                {
                    height -= 5;
                    temp = mainWindow.Height - height;
                    if ((temp > mainWindow.MinHeight) && (temp < mainWindow.MaxHeight))
                    {
                        mainWindow.Height = temp;
                        mainWindow.Top += height;
                    }
                }
            }
        }
    }

答案 2 :(得分:0)

对于 @GMIKE 答案,您需要这个字符串扩展方法(取自 here):

public static class StringExtensions
{
    public static bool Contains(this string source, string toCheck, StringComparison comp)
    {
        return source?.IndexOf(toCheck, comp) >= 0;
    }
}