WPF/C#:更改界面的样式

简介: WPF/C#:更改界面的样式

项目结构:

先来看看BlueSkin.xaml与YellowSkin.xaml。

BlueSkin.xaml:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SkinnedApplication">
  <Style TargetType="{x:Type Button}">
    <Setter Property="Background" Value="Blue" />
  </Style>
  <Style TargetType="{x:Type local:ChildWindow}">
    <Setter Property="Background" Value="Blue" />
  </Style>
  <Style TargetType="{x:Type local:MainWindow}">
    <Setter Property="Background" Value="Blue" />
  </Style>
</ResourceDictionary>

YellowSkin.xaml:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SkinnedApplication">
  <Style TargetType="{x:Type Button}">
    <Setter Property="Background" Value="Yellow" />
  </Style>
  <Style TargetType="{x:Type local:ChildWindow}">
    <Setter Property="Background" Value="Yellow" />
  </Style>
  <Style TargetType="{x:Type local:MainWindow}">
    <Setter Property="Background" Value="Yellow" />
  </Style>
</ResourceDictionary>

都是在ResourceDictionary中包含了一些Style。

资源字典(ResourceDictionary)介绍

现在来看看ResourceDictionary是什么?

在WPF中,资源字典(ResourceDictionary)是一个非常重要的特性,它用于存储和管理可重用的资源,如样式、控件模板、颜色、字体等。通过使用ResourceDictionary,你可以在一个集中的位置定义这些资源,并在整个应用程序中重用它们,这有助于保持应用程序的一致性和减少代码的重复。

资源字典是应用使用的 XAML 资源(如样式)的存储库。 在 XAML 中定义资源,然后可以使用 {StaticResource} 标记扩展和 {ThemeResource} 标记扩展在 XAML 中检索它们。 还可以使用代码访问资源,但这并不常见。 你可以使用资源来强制在整个应用中一致地使用某些值,例如画笔颜色或像素度量。

样式(Style)介绍

知道了ResourceDictionary是什么,现在再来看看Style是什么?

在WPF中,样式(Style)是一种定义一组属性值的方式,这些属性值可以应用于一个或多个UI元素,以此来改变它们的外观和行为。样式类似于CSS(层叠样式表)中的样式,它允许开发者在一个集中的位置定义UI元素的外观,然后在整个应用程序中重用这些定义。

Style类在类型的不同实例之间共享属性、资源和事件处理程序。

可以这样子使用:

<Style x:Key="Style1">
  <Setter Property="Control.Background" Value="Yellow"/>
</Style>

应用它,只需要这样子写:

<Label Content="Yellow Background" Style="{StaticResource Style1}" />

还可以使用 TargetType 属性将样式应用于给定类型的所有元素。 将目标类型添加到样式意味着不再需要使用语法完全限定所设置 ClassName.PropertyName 的属性。 以下示例定义将应用于每个 TextBlock 元素的样式。

<Style TargetType="{x:Type TextBlock}">
  <Setter Property="FontFamily" Value="Segoe Black" />
  <Setter Property="HorizontalAlignment" Value="Center" />
  <Setter Property="FontSize" Value="12pt" />
  <Setter Property="Foreground" Value="#777777" />
</Style>

以上的BlueSkin.xaml与YellowSkin.xaml就是使用这种用法。

将资源字典加载到应用程序属性字典

App.xaml:

<Application x:Class="SkinnedApplication.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:SkinnedApplication"
             StartupUri="MainWindow.xaml" Startup="App_Startup" />

其中

Startup="App_Startup"

Startup是Application类的一个事件,当应用程序启动并准备好运行时触发。这个事件在应用程序的主窗口显示之前发生,因此它是执行初始化操作(如加载资源、配置或数据)的理想位置。

App_Startup是这个事件的处理程序,在App.cs中定义:

private void App_Startup(object sender, StartupEventArgs e)
 {
     Properties["Blue"] = (ResourceDictionary) LoadComponent(new Uri("BlueSkin.xaml", UriKind.Relative));
     Properties["Yellow"] = (ResourceDictionary) LoadComponent(new Uri("YellowSkin.xaml", UriKind.Relative));
 }

这段代码位其目的是在应用程序启动时加载两个资源字典,分别代表两种不同的皮肤或主题,然后将这些资源字典存储在应用程序的属性字典中以供后续使用。

Properties是Application类的一个属性,它提供了一个键值对的集合,可以用来存储应用程序范围内的数据。

LoadComponent方法是WPF中用于加载XAML文件并创建相应对象的方法。

在这里我们又遇到了一个新的概念:属性字典(Properties Dictionary)。

属性字典(Properties Dictionary)介绍

在WPF应用程序中,属性字典(Properties Dictionary)是Application类提供的一个功能,允许开发者在应用程序范围内存储和检索键值对数据。这个属性字典可以用来保存应用程序的配置信息、状态数据或者任何需要在不同组件或页面间共享的数据。

属性字典的主要特点包括:

  • 应用程序范围:存储在属性字典中的数据在整个应用程序的生命周期内都是可用的,这意味着不同的窗口、页面或控件都可以访问和修改这些数据。
  • 键值对存储:属性字典以键值对的形式存储数据,其中键是一个唯一的字符串,值可以是任何类型的对象。
  • 动态类型:由于属性字典中的值是以object类型存储的,因此在检索值时通常需要进行类型转换。

属性字典非常适合用来存储那些需要在应用程序的多个部分之间共享的数据,但是它不适合用来存储大量的数据或者需要频繁更新的数据,因为这可能会影响应用程序的性能。

切换样式的实现

MainWindow.xaml如下:

<Window x:Class="SkinnedApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:SkinnedApplication"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <Button Name="newChildWindowButton" Click="newChildWindowButton_Click">New ChildWindow</Button>
        <StackPanel Orientation="Horizontal">
            <Label>Skin:</Label>
            <ComboBox Name="skinComboBox" />
        </StackPanel>
    </StackPanel>
</Window>

MainWindow.cs如下:

using System.Windows;
using System.Windows.Controls;
namespace SkinnedApplication
{
    /// <summary>
    ///     Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            // Add choices to combo box
            skinComboBox.Items.Add("Blue");
            skinComboBox.Items.Add("Yellow");
            skinComboBox.SelectedIndex = 0;
            // Set initial skin
            Application.Current.Resources = (ResourceDictionary) Application.Current.Properties["Blue"];
            // Detect when skin changes
            skinComboBox.SelectionChanged += skinComboBox_SelectionChanged;
        }
        private void newChildWindowButton_Click(object sender, RoutedEventArgs e)
        {
            // Create a new skind child window
            var window = new ChildWindow();
            window.Show();
        }
        private void skinComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // Change the skin
            var selectedValue = (string) e.AddedItems[0];
            Application.Current.Resources = (ResourceDictionary) Application.Current.Properties[selectedValue];
        }
    }
}
Application.Current.Resources = (ResourceDictionary) Application.Current.Properties["Blue"];

初始化一个主题或者皮肤。

Application.Current.Resources = (ResourceDictionary) Application.Current.Properties[selectedValue];

切换样式。

最终实现的效果如下所示:

切换到:

总结

通过这个例子我们简单了解了WPF中的资源字典(ResourceDictionary)、样式(Style)、属性字典(Properties Dictionary)以及一种实现WPF应用更换主题的思路,希望对你有所帮助。

参考

1、ResourceDictionary 类 (Windows.UI.Xaml) - Windows UWP applications | Microsoft Learn

2、Style 类 (System.Windows) | Microsoft Learn

3、Application.Properties 属性 (System.Windows) | Microsoft Learn

代码来源

[WPF-Samples/Application Management/SkinnedApplication at main · microsoft/WPF-Samples (github.com)]

目录
相关文章
|
19天前
|
开发者 C# 存储
WPF开发者必读:资源字典应用秘籍,轻松实现样式与模板共享,让你的WPF应用更上一层楼!
【8月更文挑战第31天】在WPF开发中,资源字典是一种强大的工具,用于共享样式、模板、图像等资源,提高了应用的可维护性和可扩展性。本文介绍了资源字典的基础知识、创建方法及最佳实践,并通过示例展示了如何在项目中有效利用资源字典,实现资源的重用和动态绑定。
34 0
|
19天前
|
C# UED 开发者
WPF动画大揭秘:掌握动画技巧,让你的界面动起来,告别枯燥与乏味!
【8月更文挑战第31天】在WPF应用开发中,动画能显著提升用户体验,使其更加生动有趣。本文将介绍WPF动画的基础知识和实现方法,包括平移、缩放、旋转等常见类型,并通过示例代码展示如何使用`DoubleAnimation`创建平移动画。此外,还将介绍动画触发器的使用,帮助开发者更好地控制动画效果,提升应用的吸引力。
41 0
|
19天前
|
容器 C# 开发者
XAML语言大揭秘:WPF标记的魅力所在,让你轻松实现界面与逻辑分离,告别复杂代码!
【8月更文挑战第31天】XAML提供了一种直观且易于维护的界面设计方式,使得开发者可以专注于逻辑和业务代码的编写,而无需关心界面细节。通过数据绑定、布局管理和动画效果等特性,XAML可以实现丰富的界面交互和视觉效果。在实际开发过程中,开发者应根据具体需求选择合适的技术方案,以确保应用程序能够满足用户的需求。希望本文的内容能够帮助您在WPF应用程序开发中更好地利用XAML语言。
31 0
|
19天前
|
开发者 C# 存储
WPF开发者必读:样式与模板的艺术,轻松定制UI外观,让你的应用程序更上一层楼!
【8月更文挑战第31天】在WPF应用开发中,样式与模板是实现美观界面与一致性的关键工具。样式定义了控件如字体、颜色等属性,而模板则允许自定义控件布局与子控件,两者均可存储于`.xaml`文件中。本文介绍了样式与模板的基础知识,通过示例展示了如何创建并应用它们来改变按钮的外观,从而提升用户体验。
25 0
|
19天前
|
数据处理 开发者 C#
WPF数据绑定实战:从零开始,带你玩转数据与界面同步,让你的应用程序更上一层楼!
【8月更文挑战第31天】在WPF应用开发中,数据绑定是核心技能之一,它能实现界面元素与数据源的同步更新。本文详细介绍了WPF数据绑定的概念与实现方法,包括属性绑定、元素绑定及路径绑定等技术,并通过示例代码展示了如何创建数据绑定。通过数据绑定,开发者不仅能简化代码、提高可维护性,还能提升用户体验。无论初学者还是有经验的开发者,都能从中受益,更好地掌握WPF数据绑定技巧。
24 0
|
19天前
|
Android开发 iOS开发 C#
Xamarin.Forms:从零开始的快速入门指南——打造你的首个跨平台移动应用,轻松学会用C#和XAML构建iOS与Android通用界面的每一个步骤
【8月更文挑战第31天】Xamarin.Forms 是一个强大的框架,让开发者通过单一共享代码库构建跨平台移动应用,支持 iOS、Android 和 Windows。使用 C# 和 XAML,它简化了多平台开发流程并保持一致的用户体验。本指南通过创建一个简单的 “HelloXamarin” 应用演示了 Xamarin.Forms 的基本功能和工作原理。
27 0
|
1月前
|
前端开发 C# 容器
WPF/C#:实现导航功能
WPF/C#:实现导航功能
37 0
|
1月前
|
设计模式 测试技术 C#
WPF/C#:在WPF中如何实现依赖注入
WPF/C#:在WPF中如何实现依赖注入
33 0
|
1月前
|
前端开发 C# Windows
WPF/C#:如何实现拖拉元素
WPF/C#:如何实现拖拉元素
41 0
|
1月前
|
存储 C# 索引
WPF/C#:BusinessLayerValidation
WPF/C#:BusinessLayerValidation
28 0