2017-05-14 2 views
0

Ich erstelle einen benutzerdefinierten Fensterstil in WPF. Bis jetzt konnte ich etwas erreichen, was fast funktioniert, in reinem XAML.Benutzerdefinierte Beschriftungsschaltflächen in 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> 

jedoch die im Fenster Chromtasten markieren oder ändern sich nicht, um den Cursor (Tasten und mit dem gleichen Stil verhalten sich wie beabsichtigt). Ein Klick darauf hat keine Wirkung. Warum ist das? Wie bekomme ich die Schaltflächen interaktiv?

Als ich das Fenster öffne, bekomme ich so etwas wie diese: an example window

Ich würde auch den schwarzen Rand in der Lage sein mag zu beheben, aber mein Hauptproblem ist die Tatsache, dass die Beschriftung Tasten noninteractive sind.

Antwort

2

Ich habe beide Probleme gelöst. Es stellt sich heraus, dass die SystemCommands Implementierungen nicht haben, und stattdessen sind nur RoutedCommand s. (Warum haben sie das gemacht?)

Also habe ich eine angefügte Eigenschaft, die die CommandBindings für jedes Fenster setzt, dass ich diesen Stil anwenden.

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 
        )); 
     } 
    } 
} 

Ich hatte die Befestigung des CommandBindings in der Eigenschaft Änderungs-Handler zu setzen, da WPF SetValue() direkt aufruft. Jetzt, in meinem Stil, fügte ich die Zeile hinzu:

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

Jetzt funktionieren die Schaltflächen wie erwartet. Um den schwarzen Rahmen zu fixieren, setze ich die Breite des äußersten Border in meiner Vorlage auf {TemplateBinding Width}. Aber das erzeugt das Problem, einen massiven, allumfassenden schwarzen Rand zu haben, wenn ich das Fenster maximiere: enter image description here

Verwandte Themen