WPF中的自定义标题按钮

时间:2017-05-14 09:25:23

标签: c# wpf

我在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按钮不会突出显示或更改光标(并且具有相同样式的按钮的行为与预期相同)。点击它们没有任何效果。为什么是这样?如何让按钮互动?

当我第一次打开窗口时,我得到这样的东西: an example window

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

1 个答案:

答案 0 :(得分: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