C# WPF中的自定义标题按钮

C# WPF中的自定义标题按钮,c#,wpf,C#,Wpf,我正在WPF中创建自定义窗口样式。到目前为止,我已经能够用纯XAML完成一些几乎可以工作的事情 <ControlTemplate TargetType="{x:Type Window}"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding B

我正在WPF中创建自定义窗口样式。到目前为止,我已经能够用纯XAML完成一些几乎可以工作的事情

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

;
;
;
但是,窗口中的chrome按钮不会高亮显示或更改光标(具有相同样式的按钮的行为与预期相同)。点击它们没有效果。为什么会这样?如何使按钮具有交互性

当我第一次打开窗户时,我得到了如下结果:


我也希望能够修复黑色边框,但我的主要问题是字幕按钮是非交互的。

我已经解决了这两个问题。原来
SystemCommands
没有实现,而是
routedcommands
s。(他们为什么这么做?)

因此,我创建了一个附加属性,为我应用此样式的每个窗口设置
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
                    ));
        }
    }
}
由于WPF直接调用
SetValue()
,我不得不将
CommandBindings
的附件放在属性更改处理程序中。现在,以我的风格,我添加了一行:

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

现在按钮按预期工作。为了修复黑色边框,我将模板中最外层的
边框的宽度设置为
{TemplateBinding width}
。但如果我将窗口最大化,就会产生一个巨大的、全方位的黑色边框的问题:
我已经解决了这两个问题。原来
SystemCommands
没有实现,而是
routedcommands
s。(他们为什么这么做?)

因此,我创建了一个附加属性,为我应用此样式的每个窗口设置
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
                    ));
        }
    }
}
由于WPF直接调用
SetValue()
,我不得不将
CommandBindings
的附件放在属性更改处理程序中。现在,以我的风格,我添加了一行:

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

现在按钮按预期工作。为了修复黑色边框,我将模板中最外层的
边框的宽度设置为
{TemplateBinding width}
。但如果我将窗口最大化,就会产生一个巨大的、全方位的黑色边框的问题: