2011-05-25 88 views
3

当使用WindowChromedownloadable here)自定义窗口的非客户区域时,自然的起点是创建一个标题栏,该标题栏的外观和行为与标准标题栏相同。这需要增加一个“假”的应用程序图标和标题栏,因为很明显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)); 
} 

这非常接近工作。第一个问题是,单击应用程序图标并出现系统菜单后,如果再次单击该菜单,该菜单应该消失 - 而只是重新绘制菜单。此外,如果您双击然后该窗口应该关闭,但图像没有双击事件。你会如何建议添加这些功能?

回答

1

我的xaml不完全相似(我没有使用WindowChrome,但是我自己也有一个titlebar模板),但是我有完全相同的问题,并且解决方案也应该可以使用。

首先简单:双击工作只需使用ClickCount。

然后,使菜单消失需要保持一些状态,告诉它是否当前是活动的:诀窍是在第二次点击时触发不同的事件(通过使用Snoop得出第一次点击只是MousweDown ,二是的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; 
} 
3

要禁用标准镀铬按钮的工作只是在你的XAML代码添加额外的属性CaptionHeight="0"shell:WindowsChrome

所以它会像那

<Setter Property="shell:WindowChrome.WindowChrome"> 
    <Setter.Value> 
     <shell:WindowChrome CaptionHeight="0" /> 
    </Setter.Value> 
</Setter> 

做一个假铬。修改模板,以这样的:

<ControlTemplate TargetType="Window"> 
    <AdornerDecorator> 
     <Grid> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="35" /> 
       <RowDefinition Height="*" />     
      </Grid.RowDefinitions> 
      <Grid x:Name="PART_Chrome" shell:WindowChrome.IsHitTestVisibleInChrome="True"> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="50" /> 
        <ColumnDefinition Width="*" /> 
        <ColumnDefinition Width="105" /> 
       </Grid.ColumnDefinitions> 

       <Image Source="Application Favicon Path" /> 

       <TextBlock Grid.Column="1" Text="{TemplateBinding Title}" VerticalAlignment="Center" /> 

       <StackPanel Orientation="Horizontal" Grid.Column="3" > 
        <Button Command="{Binding Source={x:Static shell:SystemCommands.MinimizeWindowCommand}}" > 
         <Path Data="M0,6 L8,6 Z" Width="8" Height="7" VerticalAlignment="Center" HorizontalAlignment="Center" 
           Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="2" /> 
        </Button> 
        <Button x:Name="MaximizeButton" Command="{Binding Source={x:Static shell:SystemCommands.MaximizeWindowCommand}}" > 
         <Path Data="M0,1 L9,1 L9,8 L0,8 Z" Width="9" Height="8" VerticalAlignment="Center" HorizontalAlignment="Center" 
           Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="2" /> 
        </Button> 
        <Button x:Name="RestoreButton" Command="{Binding Source={x:Static shell:SystemCommands.RestoreWindowCommand}}" > 
         <Path Data="M2,0 L8,0 L8,6 M0,3 L6,3 M0,2 L6,2 L6,8 L0,8 Z" Width="8" Height="8" VerticalAlignment="Center" HorizontalAlignment="Center" 
           Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="1" /> 
        </Button> 
        <Button Command="{Binding Source={x:Static shell:SystemCommands.CloseWindowCommand}}" > 
         <Path Data="M0,0 L8,7 M8,0 L0,7 Z" Width="8" Height="7" VerticalAlignment="Center" HorizontalAlignment="Center" 
           Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="1.5" /> 
        </Button> 
       </StackPanel> 
      </Grid> 
      <ContentPresenter Grid.Row="1" Content="{TemplateBinding Content}" /> 
     </Grid> 
    </AdornerDecorator> 
    <ControlTemplate.Triggers> 
     <Trigger Property="WindowState" Value="Normal">    
      <Setter Property="Visibility" Value="Collapsed" TargetName="RestoreButton" /> 
      <Setter Property="Visibility" Value="Visible" TargetName="MaximizeButton" /> 
     </Trigger> 
     <Trigger Property="WindowState" Value="Maximized"> 
      <Setter Property="Visibility" Value="Visible" TargetName="RestoreButton" /> 
      <Setter Property="Visibility" Value="Collapsed" TargetName="MaximizeButton" /> 
     </Trigger> 
    </ControlTemplate.Triggers> 
</ControlTemplate> 

还做命令假镀铬条的正常工作结合

public MainWindow() 
{ 
    this.CommandBindings.Add(new CommandBinding(SystemCommands.CloseWindowCommand, OnCloseWindow)); 
    this.CommandBindings.Add(new CommandBinding(SystemCommands.MaximizeWindowCommand, OnMaximizeWindow, OnCanResizeWindow)); 
    this.CommandBindings.Add(new CommandBinding(SystemCommands.MinimizeWindowCommand, OnMinimizeWindow, OnCanMinimizeWindow)); 
    this.CommandBindings.Add(new CommandBinding(SystemCommands.RestoreWindowCommand, OnRestoreWindow, OnCanResizeWindow)); 

} 

private void OnCanMinimizeWindow(object sender, CanExecuteRoutedEventArgs e) 
{ 
    e.CanExecute = this.ResizeMode != ResizeMode.NoResize; 
} 

private void OnCanResizeWindow(object sender, CanExecuteRoutedEventArgs e) 
{ 
    e.CanExecute = this.ResizeMode == ResizeMode.CanResize || this.ResizeMode == ResizeMode.CanResizeWithGrip; 
} 

private void OnCloseWindow(object sender, ExecutedRoutedEventArgs e) 
{ 
    Microsoft.Windows.Shell.SystemCommands.CloseWindow(this); 
} 

private void OnMaximizeWindow(object sender, ExecutedRoutedEventArgs e) 
{ 
    Microsoft.Windows.Shell.SystemCommands.MaximizeWindow(this); 
} 

private void OnMinimizeWindow(object sender, ExecutedRoutedEventArgs e) 
{ 
    Microsoft.Windows.Shell.SystemCommands.MinimizeWindow(this); 
} 

private void OnRestoreWindow(object sender, ExecutedRoutedEventArgs e) 
{ 
    Microsoft.Windows.Shell.SystemCommands.RestoreWindow(this); 
} 
+1

有一件事失踪,使这个_the_完美的解决方案:设置'WindowChrome.IsHitTestVisibleInChrome =”在“StackPanel”中的True“'会使窗口双击并拖动。 (@Pushpraj在他对[C#| WPF - 自定义标题栏 - 最大化时从顶部拖动窗口不起作用]的答案](https://stackoverflow.com/questions/24654845/c-sharp-wpf-custom-title-棒拖窗口从机上时最大化-犯规-WO#24654932))。 – Informagic 2017-07-12 07:18:52