2017-05-14 109 views
0

我正在WPF中创建自定义窗口样式。到目前为止,我已经能够在纯XAML中完成几乎可以工作的内容。WPF中的自定义标题按钮

<ControlTemplate TargetType="{x:Type Window}"> 
    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" 
     Background="{TemplateBinding Background}"> 
     <DockPanel LastChildFill="True"> 
     <Border Height="40" Padding="5" DockPanel.Dock="Top" BorderBrush="#7FA0A0A0" 
      BorderThickness="0,0,0,1"> 
      <Grid WindowChrome.IsHitTestVisibleInChrome="True"> 
      <StackPanel Orientation="Horizontal" HorizontalAlignment="Left"> 
       <Image Source="Resources/Logo/f-dark.png" /> 
       <TextBlock Margin="0,0,0,0" Text="{TemplateBinding Title}" VerticalAlignment="Center" 
       FontSize="16" Foreground="#AF000000"/> 
      </StackPanel> 
      <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" 
        WindowChrome.IsHitTestVisibleInChrome="True" Background="Transparent"> 
       <Button Width="{x:Static SystemParameters.WindowCaptionButtonWidth}" 
        Command="{x:Static SystemCommands.MinimizeWindowCommand}" 
        Style="{StaticResource LinkButton}" 
        WindowChrome.IsHitTestVisibleInChrome="True" 
        IsEnabled="True"> 
       <TextBlock Style="{StaticResource Icon}" FontSize="18">&#xE15B;</TextBlock> 
       </Button> 
       <Button Width="{x:Static SystemParameters.WindowCaptionButtonWidth}" 
        Command="{x:Static SystemCommands.RestoreWindowCommand}" 
        Style="{StaticResource LinkButton}" 
        WindowChrome.IsHitTestVisibleInChrome="True" 
        IsEnabled="True"> 
       <TextBlock Style="{StaticResource Icon}" FontSize="18">&#xE5D0;</TextBlock> 
       </Button> 
       <Button Width="{x:Static SystemParameters.WindowCaptionButtonWidth}" 
        Command="{x:Static SystemCommands.CloseWindowCommand}" 
        Style="{StaticResource LinkButton}" 
        WindowChrome.IsHitTestVisibleInChrome="True" 
        IsEnabled="True"> 
       <TextBlock Style="{StaticResource Icon}" FontSize="18">&#xE5CD;</TextBlock> 
       </Button> 
      </StackPanel> 
      </Grid> 

     </Border> 
     <Border> 
      <ContentPresenter/> 
     </Border> 

     </DockPanel> 
    </Border> 
</ControlTemplate> 

然而,在该窗口镀铬按钮不突出或改变光标(和按键使用相同的风格表现为意)。点击它们不起作用。为什么是这样?我如何获得按钮是互动的?

当我第一次打开的窗口中,我得到的是这样的: an example window

我也想能够修复的黑边,但我的主要问题是,标题按钮非交互。

回答

2

我已经解决了这两个问题。事实证明,SystemCommands没有实现,而只是RoutedCommand。 (他们为什么这样做呢?)

所以,我做了一个附加属性,该属性设置为CommandBindings,我将此风格,每个窗口。

public class Helper 
{ 
    public static bool GetUseWindowCommandBindings(DependencyObject obj) 
    { 
     return (bool)obj.GetValue(UseWindowCommandBindingsProperty); 
    } 

    public static void SetUseWindowCommandBindings(DependencyObject obj, bool value) 
    { 
     obj.SetValue(UseWindowCommandBindingsProperty, value); 
    } 

    public static readonly DependencyProperty UseWindowCommandBindingsProperty = 
     DependencyProperty.RegisterAttached("UseWindowCommandBindings", typeof(bool), typeof(Helper), new PropertyMetadata(false, UseWindowCommandBindingsChanged)); 

    private static void UseWindowCommandBindingsChanged(DependencyObject d, DependencyPropertyChangedEventArgs dpce) 
    { 
     if (d is Window w && dpce.NewValue is bool b && b) 
     { 
      w.CommandBindings.Add(
       new CommandBinding(
        SystemCommands.MinimizeWindowCommand, 
        (s, e) => SystemCommands.MinimizeWindow(w), 
        (s, e) => e.CanExecute = true 
        )); 
      w.CommandBindings.Add(
       new CommandBinding(
        SystemCommands.RestoreWindowCommand, 
        (s, e) => SystemCommands.RestoreWindow(w), 
        (s, e) => e.CanExecute = true 
        )); 
      w.CommandBindings.Add(
       new CommandBinding(
        SystemCommands.MaximizeWindowCommand, 
        (s, e) => SystemCommands.MaximizeWindow(w), 
        (s, e) => e.CanExecute = true 
        )); 
      w.CommandBindings.Add(
       new CommandBinding(
        SystemCommands.CloseWindowCommand, 
        (s, e) => SystemCommands.CloseWindow(w), 
        (s, e) => e.CanExecute = true 
        )); 
     } 
    } 
} 

我不得不把CommandBindings的附着在属性更改处理程序,因为WPF直接调用SetValue()。现在,在我的风格中,我添加了这一行:

<Setter Property="view:Helper.UseWindowCommandBindings" Value="True" /> 

现在按钮按预期工作。要修复黑色边框,我将我模板中最外面的Border的宽度设置为{TemplateBinding Width}。但是,如果我最大化窗口,会产生一个巨大的全黑色边框的问题: enter image description here