3

WindowChrome (ここからダウンロード可能) を使用してウィンドウの非クライアント領域をカスタマイズする場合、自然な出発点は、標準のタイトル バーと同じ外観と動作のタイトル バーを作成することです。これには、「偽の」アプリケーション アイコンとタイトル バーを追加する必要があります。これは、明らかに WindowChrome がこれらの機能を無効にするためです (最小化、最大化、閉じるボタンは引き続き機能します)。

これが私がこれまでに持っているものです:

<Window x:Class="MyApp.MainWindow"
        x:Name="MainWindowItself"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:shell="clr-namespace:Microsoft.Windows.Shell;assembly=Microsoft.Windows.Shell"
        xmlns:local="clr-namespace:MyApp"
        Title="My Application" Icon="App.ico" Height="350" Width="525">
    <Window.Resources>
        <Style TargetType="{x:Type local:MainWindow}">
            <Setter Property="shell:WindowChrome.WindowChrome">
                <Setter.Value>
                    <shell:WindowChrome />
                </Setter.Value>
            </Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:MainWindow}">
                        <Grid>
                            <Border Background="White" Margin="{Binding Source={x:Static shell:SystemParameters2.Current}, Path=WindowNonClientFrameThickness}">
                                <ContentPresenter Content="{TemplateBinding Content}" />
                            </Border>
                            <TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Title}" 
                               VerticalAlignment="Top" HorizontalAlignment="Left" 
                               Margin="32,8,0,0"/>
                            <Image x:Name="SystemMenuIcon" Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Icon}"
                               VerticalAlignment="Top" HorizontalAlignment="Left"
                               Margin="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(shell:WindowChrome.WindowChrome).ResizeBorderThickness}" 
                               Width="{Binding Source={x:Static shell:SystemParameters2.Current}, Path=SmallIconSize.Width}"
                               shell:WindowChrome.IsHitTestVisibleInChrome="True" MouseDown="SystemMenuIcon_MouseDown">
                            </Image>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <TextBlock Text="Client area content goes here"/>
    </Grid>
</Window>

コードビハインド:

private void SystemMenuIcon_MouseDown(object sender, MouseButtonEventArgs e)
{
    var offs = SystemParameters2.Current.WindowNonClientFrameThickness;
    SystemCommands.ShowSystemMenu(this, new Point(Left + offs.Left, Top + offs.Top));
}

これは、作業に非常に近いものです。最初の問題は、アプリケーション アイコンをクリックしてシステム メニューが表示された後、もう一度クリックするとメニューが消えてしまい、代わりにメニューが再描画されることです。また、ダブルクリックするとウィンドウが閉じますが、Image にはダブルクリック イベントがありません。これらの機能を追加することをどのように提案しますか?

4

2 に答える 2

1

私のxamlはまったく同じではありません(私はWindowChromeを使用していませんが、私自身のもので、タイトルバーテンプレートを持っています)が、まったく同じ問題があり、ソリューションはあなたにも使用できるはずです.

最初の簡単な方法: ダブルクリックを機能させるには、ClickCount を使用するだけです。

次に、メニューを非表示にするには、現在アクティブかどうかを示すいくつかの状態を維持する必要があります: トリックは、2 回目のクリックで異なるイベントが発生することです ( Snoopを使用して理解したように。最初のクリックは MousweDown のみであり、2 回目はMouseDown の後に MouseUp が続きます (私の推測では、最初のクリックからのアップは sysmenu によって処理されます)。

private bool inSysMenu = false;

void SystemMenuIcon_MouseDown( object sender, MouseButtonEventArgs e )
{
  if( e.ClickCount == 1 && !inSysMenu )
  {
    inSysMenu = true;
    ShowSystemMenu(); //replace with your code
  }
  else if( e.ClickCount == 2 && e.ChangedButton == MouseButton.Left )
  {
    window.Close();
  }
}

void SystemMenuIcon_MouseLeave( object sender, MouseButtonEventArgs e )
{
  inSysMenu = false;
}

void SystemMenuIcon_MouseUp( object sender, MouseButtonEventArgs e )
{
  inSysMenu = false;
}
于 2011-11-11T09:50:34.753 に答える