📜  亚克力 UWP 标题栏 C# (1)

📅  最后修改于: 2023-12-03 14:49:03.825000             🧑  作者: Mango

亚克力 UWP 标题栏 C#

在 UWP 应用程序开发中,标题栏是一个重要的组成部分,因为它包含了应用程序图标、窗口控制按钮、标题和菜单等功能。本文将介绍如何使用亚克力和 C# 来制作自定义的标题栏。

什么是亚克力?

亚克力(Acrylic)是 Windows 10 Fluent Design System 的一部分,它是一种扁平化的设计风格,可以使 UI 元素看起来更加清晰、透明和现代。亚克力还可以与动画、光照和混合深度等特效一起使用,提高用户的体验。

如何使用亚克力制作 UWP 标题栏

在 UWP 应用程序中,可以通过以下几个步骤实现使用亚克力制作标题栏:

  1. 在 App.xaml 中添加以下样式代码,来定义全局的标题栏样式:
<Application.Resources>
    <ResourceDictionary>
        <Style x:Key="CustomTitleBar" TargetType="AppBar">
            <Setter Property="Height" Value="32"></Setter>
            <Setter Property="Background" Value="Transparent"></Setter>
            <Setter Property="Foreground" Value="White"></Setter>
            <Setter Property="Padding" Value="0"></Setter>
            <Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
            <Setter Property="VerticalContentAlignment" Value="Center"></Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="AppBar">
                        <Grid Background="Transparent" Padding="{TemplateBinding Padding}">
                            <Grid Background="{ThemeResource SystemAccentColor}" Opacity="0.5"/>
                            <Border BorderThickness="1" BorderBrush="White">
                                <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" />
                            </Border>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ResourceDictionary>
</Application.Resources>

这里我们定义的样式名为 CustomTitleBar。该样式包含了标题栏的高度、背景、前景和内部元素等属性。

  1. 在 MainPage.xaml 中,添加以下代码来定义自定义的标题栏和窗口:
<Page
    x:Class="UWPApp.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:UWPApp"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid>
        <Canvas x:Name="TitleBarCanvas" Grid.Row="0">
            <AppBar x:Name="CustomAppBar" Style="{StaticResource CustomTitleBar}" Padding="12,0">
                <StackPanel Orientation="Horizontal">
                    <Button x:Name="BackButton" Content="&#xE112;" Style="{StaticResource BackButtonStyle}"/>
                    <TextBlock x:Name="TitleTextBlock" Text="My Custom Title Bar" Style="{StaticResource TitleTextBlockStyle}" VerticalAlignment="Center"/>
                </StackPanel>
            </AppBar>
            <TextBlock x:Name="ContentTextBlock" Text="Hello World!" FontSize="30" VerticalAlignment="Center" HorizontalAlignment="Center"/>
        </Canvas>
    </Grid>
</Page>

这里我们定义了一个 Canvas,它包含了自定义的标题栏和窗口内容。

  1. 在 MainPage.xaml.cs 中,添加以下代码来实现自定义的标题栏拖动和窗口最大化和最小化等功能:
public sealed partial class MainPage : Page
{
    private CoreApplicationViewTitleBar coreTitleBar;
    private ApplicationViewTitleBar appTitleBar;

    public MainPage()
    {
        this.InitializeComponent();

        // 获取标题栏对象
        CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = true;
        coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
        appTitleBar = ApplicationView.GetForCurrentView().TitleBar;

        // 自定义标题栏
        UpdateTitleBarLayout(coreTitleBar.IsVisible);

        // 标题栏可见性改变事件
        coreTitleBar.LayoutMetricsChanged += CoreTitleBar_LayoutMetricsChanged;

        // 标题栏可见性改变事件
        Window.Current.SetTitleBar(TitleBarCanvas);
        Window.Current.Activated += Current_Activated;
    }

    // 标题栏可见性改变事件回调函数
    private void CoreTitleBar_LayoutMetricsChanged(CoreApplicationViewTitleBar sender, object args)
    {
        Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {
            UpdateTitleBarLayout(sender.IsVisible);
        });
    }

    // 标题栏活动状态改变事件回调函数
    private void Current_Activated(object sender, WindowActivatedEventArgs e)
    {
        appTitleBar.ForegroundColor = e.WindowActivationState == CoreWindowActivationState.Deactivated ? Colors.Gray : Colors.White;
    }

    // 自定义标题栏
    private void UpdateTitleBarLayout(bool isVisible)
    {
        appTitleBar.BackgroundColor = isVisible ? Colors.Transparent : Colors.Transparent;
        appTitleBar.ButtonBackgroundColor = isVisible ? Colors.Transparent : Colors.Transparent;
        appTitleBar.ForegroundColor = isVisible ? Colors.White : Colors.Gray;
    }

    // 窗口最小化事件
    private void AppTitleBar_SystemOverlayCloseOnClick(object sender, object e)
    {
        Application.Current.Exit();
    }

    // 窗口最小化事件
    private void AppTitleBar_SystemOverlayMinimizeOnClick(object sender, object e)
    {
        appTitleBar.ButtonBackgroundColor = Colors.Transparent;
        appTitleBar.ButtonForegroundColor = Colors.White;
        Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {
            ApplicationView.GetForCurrentView().TryEnterFullScreenMode();
        });
    }

    // 窗口还原事件
    private void AppTitleBar_SystemOverlayRestoreOnClick(object sender, object e)
    {
        appTitleBar.ButtonBackgroundColor = Colors.Transparent;
        appTitleBar.ButtonForegroundColor = Colors.White;
        Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {
            ApplicationView.GetForCurrentView().ExitFullScreenMode();
        });
    }

    // 标题栏拖动事件
    private void AppTitleBar_DragAppWindow(object sender, DragEventArgs e)
    {
        e.Handled = true;
        Window.Current.CoreWindow.PointerPosition = new Point(e.GetPosition(null).X, Window.Current.CoreWindow.PointerPosition.Y);
    }
}

这里我们使用了 CoreApplicationViewTitleBar 和 ApplicationViewTitleBar 来获取和自定义标题栏,使用了 WindowActivationState 来区分窗口活动状态。我们还实现了一些事件回调函数来处理窗口最大化、最小化和还原等操作。

总结

本文介绍了如何使用亚克力和 C# 来制作自定义的标题栏。我们需要先定义一个全局的标题栏样式,在 MainPage.xaml 中添加自定义的标题栏和窗口,并在 MainPage.xaml.cs 中实现标题栏的拖动和窗口最大化、最小化和还原等功能。