【问题标题】:Dragging custom window title bar from top when maximized does not work最大化时从顶部拖动自定义窗口标题栏不起作用
【发布时间】:2014-08-30 13:08:37
【问题描述】:

我有一个自定义标题栏,并且窗口样式设置为无。单击标题栏时,我检查是否是双击(即窗口最大化和恢复),如果没有双击,我会执行Window.DragMove。这非常适合捕捉到侧面和顶部。但是当我尝试在窗口最大化时拖动窗口(这通常会恢复窗口),它什么也没做。这是我的代码:

    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

Modern UI 和 MahApps.Metro 以某种方式做到了这一点,我简要查看了他们的源代码,但找不到他们是如何做到的。

提前致谢。

【问题讨论】:

    标签: c# wpf window customization titlebar


    【解决方案1】:

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

    结果你可以看到一个自定义的标题栏,它是完全可拖动的,双击最大化和恢复,拖动捕捉和取消捕捉。

    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>
    

    结果

    所以现在您不需要任何代码来手动处理标题栏。

    可重复使用的样式

    您还可以将其包裹在可以应用于多个窗口的自定义样式中

    <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

    查看您的代码后,我确实设法通过很少的更改来实现它

    变化是

    文件: CustomChrome.cs

    第 41 行:更改 CaptionHeight = 36,目前为 0。这应该等于您的标题栏高度

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

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

    第 70 行:删除不再使用的事件 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">
    

    就是这样,您的应用将有一个正常的标题栏,无需处理自定义逻辑

    【讨论】:

    • 我试过了,但没有用。然后它做了一些时髦的事情。
    • 您可以发布您的应用程序的工作示例吗?我可以在这里试试吗?
    • 你知道怎么做吗?
    • 您是否设置了WindowChrome.IsHitTestVisibleInChrome="True",这是这些按钮工作所必需的。您也可以单独设置按钮。
    • 自定义窗口效果很好,但是当您最大化和最小化窗口时它会丢失一些小动画,它只是突然弹出并突然隐藏。你知道如何实现默认的最小化和最大化效果吗?
    猜你喜欢
    • 2011-11-05
    • 1970-01-01
    • 1970-01-01
    • 2012-10-09
    • 2011-09-17
    • 1970-01-01
    • 2021-04-08
    • 1970-01-01
    • 2021-03-30
    相关资源
    最近更新 更多