web-dev-qa-db-ja.com

最大化時にカスタムウィンドウのタイトルバーを上からドラッグしても機能しない

カスタムタイトルバーがあり、ウィンドウスタイルがnoneに設定されています。タイトルバーをクリックすると、ダブルクリックされているかどうかを確認します(ウィンドウが最大化されて復元されます)。ダブルクリックされていない場合は、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

最新のUIとMahApps.Metroはどういうわけかそれを行い、私はそれらのソースコードを簡単に調べましたが、それらがどのように行うかを見つけることができませんでした。

前もって感謝します。

11
James Esh

純粋なxamlでエアロスナップを含むタイトルバーの望ましい動作を得ることができます

その結果、カスタムタイトルバーが表示されます。完全にドラッグ可能です。ダブルクリックして最大化および復元し、ドラッグしてスナップおよびスナップ解除します。

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>

結果

result

そのため、タイトルバーを手動で処理するためのコードビハインドは必要ありません。

再利用可能なスタイル

複数のウィンドウに適用できるカスタムスタイルで上記をラップすることもできます

<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">

これですべてです。アプリには、カスタムロジックを処理する必要のない通常のタイトルバーがあります。

42
pushpraj