本文介绍了最大化时从顶部拖动自定义窗口标题栏不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义标题栏,并且窗口样式设置为none.在标题栏上单击时,如果不是双击则检查是否是双击(确实使窗口最大化并还原),我单击 Window.DragMove .这非常适合贴到侧面和顶部.但是,当我尝试在最大化窗口时拖动窗口时(通常会将窗口向下还原),它什么也没做.这是我的代码:

I have a custom title bar and with the window style set to none. On the click of the title bar I check to see if it is a double click (that does window maximize and restore) if it is not double clicked I do Window.DragMove. This works great for the snapping to the side and top. But when I try to drag the window when it is maximized (which would normally restore the window down), it doesn't do anything. Here is my code:

    static Window Window { get { return Application.Current.MainWindow; } }

    /// <summary>
    /// TitleBar_MouseDown - Drag if single-click, resize if double-click
    /// </summary>
    private static void TitleBar_MouseDown(object sender, MouseButtonEventArgs e)
    {
        if (e.ChangedButton == MouseButton.Left)
        {
            if (e.ClickCount == 2)
            {
                AdjustWindowSize();
            }
            else
            {
                Window.DragMove();//Here is where I do the drag move
            }
        }
    }

    /// <summary>
    /// Adjusts the WindowSize to correct parameters when Maximize button is clicked
    /// </summary>
    internal static void AdjustWindowSize()
    {
        if (Window.WindowState == WindowState.Maximized)
        {
            SystemCommands.RestoreWindow(Window);
        }
        else
        {
            SystemCommands.MaximizeWindow(Window);
        }

    }

    #region Button Events

    /// <summary>
    /// CloseButton_Clicked
    /// </summary>
    public static void Close()
    {
        SystemCommands.CloseWindow(Window);
    }

    /// <summary>
    /// MaximizedButton_Clicked
    /// </summary>
    public static void Maximize()
    {
        AdjustWindowSize();
    }

    /// <summary>
    /// Minimized Button_Clicked
    /// </summary>
    public static void Minimize()
    {
        SystemCommands.MinimizeWindow(Window);
    }

    #endregion

现代用户界面和MahApps.Metro以某种方式做到了这一点,我简要地看了看他们的源代码,但找不到他们是怎么做的.

Modern UI and MahApps.Metro does it somehow and I looked at their source code briefly but could not find how they do it.

谢谢.

推荐答案

我能够获得所需的标题栏行为,包括纯xaml中的aero snap

I am able to get the desired behavior of title bar including aero snap in pure xaml

因此,您可以看到一个自定义标题栏,该标题栏是完全可拖动的,双击以最大化和还原,然后拖动以捕捉和取消捕捉.

as result you can see a custom title bar, it is completely draggable, double click to maximize and restore and drag to snap and unsnap.

xaml

<Window x:Class="CSharpWPF.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" >
    <WindowChrome.WindowChrome>
        <WindowChrome CaptionHeight="{Binding ActualHeight,ElementName=titlebar}"/>
    </WindowChrome.WindowChrome>
    <DockPanel LastChildFill="True">
        <Border Background="LightBlue" DockPanel.Dock="Top" Height="25" x:Name="titlebar">
            <TextBlock Text="{Binding Title, RelativeSource={RelativeSource FindAncestor,AncestorType=Window},FallbackValue=Title}"
                       Margin="10,0,0,0"
                       VerticalAlignment="Center">
                <TextBlock.Effect>
                    <DropShadowEffect Color="White" ShadowDepth="3"/>
                </TextBlock.Effect>
            </TextBlock>
        </Border>
        <Border BorderBrush="LightGray" BorderThickness="1" Padding="4">
            <TextBlock Text="Window content"/>
        </Border>
    </DockPanel>
</Window>

结果

所以现在您不需要任何代码即可手动处理标题栏.

so now you don't need any code behind to handle title bar manually.

可重复使用的样式

您还可以采用自定义样式将其包裹起来,然后将其应用于多个窗口

you can also wrap above in a custom style which you can apply on several windows

<Style TargetType="Window" x:Key="CustomTitleBar">
    <Setter Property="WindowChrome.WindowChrome">
        <Setter.Value>
            <WindowChrome CaptionHeight="{x:Static SystemParameters.CaptionHeight}" />
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Window">
                <DockPanel LastChildFill="True">
                    <Border Background="LightBlue" DockPanel.Dock="Top"
                            Height="{x:Static SystemParameters.CaptionHeight}" x:Name="titlebar">
                        <Grid>
                            <TextBlock Text="{TemplateBinding Title}"
                                        Margin="10,0,0,0"
                                        VerticalAlignment="Center">
                                <TextBlock.Effect>
                                    <DropShadowEffect Color="White" ShadowDepth="3"/>
                                </TextBlock.Effect>
                            </TextBlock>
                        </Grid>
                    </Border>
                    <Border Background="{TemplateBinding Background}" BorderBrush="LightGray"
                            BorderThickness="1" Padding="4">
                        <ContentPresenter/>
                    </Border>
                </DockPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

用法

<Window x:Class="CSharpWPF.View"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                Title="MainWindow"
                Style="{StaticResource CustomTitleBar}" >
    <TextBlock Text="Window content"/>
</Window>


如何在代码中实现


How to implement in your code

查看您的代码后,我确实做了很小的改动就实现了

After looking at your code, I did manage to implement it with very little changes

更改是

文件: CustomChrome.cs

第41行:更改 CaptionHeight = 36 ,当前为0.该值应等于标题栏的高度

line 41: change CaptionHeight = 36, currently it is 0. this should be equal to your title bar height

var chrome = new WindowChrome() { GlassFrameThickness = new Thickness(-1), CaptionHeight = 36 };

第60行:删除((FrameworkElement)sender).MouseDown + = TitleBar_MouseDown; 不需要

第70行:删除不再使用的事件 TitleBar_MouseDown

line 70: remove no more used event TitleBar_MouseDown

文件: CornerButtons.xaml

第13行:将 WindowChrome.IsHitTestVisibleInChrome ="True" 添加到 StackPanel

    <StackPanel SnapsToDevicePixels="True" Orientation="Horizontal" WindowChrome.IsHitTestVisibleInChrome="True">

文件: MainWindow.xaml

第17行:将 WindowChrome.IsHitTestVisibleInChrome ="True" 添加到 StackPanel

<cc:CornerButtons Grid.Column="2">
    <StackPanel Orientation="Horizontal"
                WindowChrome.IsHitTestVisibleInChrome="True">

仅此而已,您的应用将具有正常的标题栏,而无需处理自定义逻辑

this is all, and your app will have a normal title bar without need to handle custom logic

这篇关于最大化时从顶部拖动自定义窗口标题栏不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 02:19