自学内容网 自学内容网

WPF-模板和样式

  • 在 WPF(Windows Presentation Foundation)中,模板是一种强大的机制,用于定义控件的外观。它允许你将控件的逻辑(功能)和外观(UI)分离开来。例如,一个按钮控件,其默认外观是由微软定义的,但通过模板,你可以完全改变按钮的外观,如改变它的形状、颜色、添加动画效果等。
  • 模板主要有两种类型:ControlTemplate(用于定义控件的可视结构)和 DataTemplate(用于定义数据对象的可视化表示)。

1. 控件模板ControlTemplate

1.1 在本文件中定义模板

下面XAML文件定义了两个模板,分别是Button和label控件的,在界面正文时就可以直接调用资源中的控件模板

<Window x:Class="Template.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
        Title="{Binding Title}" Height="350" Width="525" >
    <Window.Resources>
        <!-- 定义按钮控件模板 -->
        <ControlTemplate x:Key="MyButtonTemplate" TargetType="Button">
            <Border Background="LightBlue" BorderBrush="DarkBlue" 
                    BorderThickness="2" CornerRadius="5">
                <ContentPresenter HorizontalAlignment="Center"   VerticalAlignment="Center"/>
            </Border>
        </ControlTemplate>
        <!--定义Label控件模板-->
        <ControlTemplate x:Key="LabelTemplate" TargetType="Label">
            <Border Background="LightBlue" BorderBrush="DarkBlue" 
            BorderThickness="2" CornerRadius="5">
                <ContentPresenter HorizontalAlignment="Center"   VerticalAlignment="Center"/>
            </Border>
        </ControlTemplate>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <!-- 使用控件模板 -->
            <Button Template="{StaticResource MyButtonTemplate}" Content="Button 1" Width="100" Height="50"/>
            <Button Template="{StaticResource MyButtonTemplate}" Content="Button 2" Width="100" Height="50"/>
            <Label Template="{StaticResource LabelTemplate }" Content="123" Width="100" Height="40"/>
        </StackPanel>
    </Grid>
</Window>

1.2 分离资源文添加模板

也可以将资源文件脱离出来,单独管理,便于在多个界面中使用同一模板

先添加资源文件

编辑资源文件

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <!-- 定义按钮控件模板 -->
    <ControlTemplate x:Key="MyButtonTemplate" TargetType="Button">
        <Border Background="LightBlue" BorderBrush="DarkBlue" 
             BorderThickness="2" CornerRadius="5">
            <ContentPresenter HorizontalAlignment="Center"   VerticalAlignment="Center"/>
        </Border>
    </ControlTemplate>
    <!--定义Label控件模板-->
    <ControlTemplate x:Key="LabelTemplate" TargetType="Label">
        <Border Background="LightBlue" BorderBrush="DarkBlue" 
     BorderThickness="2" CornerRadius="5">
            <ContentPresenter HorizontalAlignment="Center"   VerticalAlignment="Center"/>
        </Border>
    </ControlTemplate>

</ResourceDictionary>

呈现效果跟方法一是一样的

2. 数据模板DataTemplate

2.1 定义数据模型

public  class Staff
{
    public string Name { get; set; }
    public int Age { get; set; }
}

2.2 在资源文件中定义模板

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <!-- 定义按钮控件模板 -->
    <ControlTemplate x:Key="MyButtonTemplate" TargetType="Button">
        <Border Background="LightBlue" BorderBrush="DarkBlue" 
             BorderThickness="2" CornerRadius="5">
            <ContentPresenter HorizontalAlignment="Center"   VerticalAlignment="Center"/>
        </Border>
    </ControlTemplate>
    <!--定义Label控件模板-->
    <ControlTemplate x:Key="LabelTemplate" TargetType="Label">
        <Border Background="LightBlue" BorderBrush="DarkBlue" 
     BorderThickness="2" CornerRadius="5">
            <ContentPresenter HorizontalAlignment="Center"   VerticalAlignment="Center"/>
        </Border>
    </ControlTemplate>
    <!--定义数据模板-->
    <DataTemplate x:Key="StaffDataTemplate">
        <StackPanel>
            <TextBlock Text="Name:" FontWeight="Bold"/>
            <TextBlock Text="{Binding Name}" FontWeight="Bold"/>
            <TextBlock Text="Age:" FontWeight="Bold"/>
            <TextBlock Text="{Binding Age}" Foreground="Gray"/>
        </StackPanel>
    </DataTemplate>

</ResourceDictionary>

2.3 初始化数据模型

这里用了Prism框架

public class MainWindowViewModel : BindableBase
{
    private string _title = "Prism Application";
    public string Title
    {
        get { return _title; }
        set { SetProperty(ref _title, value); }
    }
    private ObservableCollection<Staff> _people;

    public ObservableCollection<Staff> People
    {
        get { return _people; }
        set { SetProperty(ref _people, value); }
    }

    public MainWindowViewModel()
    {
        // 初始化数据
        People = new ObservableCollection<Staff>
        {
            new Staff { Name = "Alice", Age = 25 },
            new Staff { Name = "Bob", Age = 30 },
            new Staff { Name = "Charlie", Age = 35 }
        };
    }
}

2.4 应用数据模板,绑定数据

<Window x:Class="Template.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
        Title="{Binding Title}" Height="350" Width="525" >
    <Window.Resources>
        <!-- 引用外部的资源字典 -->
        <ResourceDictionary Source="ControlTemplates.xaml"/>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <!-- 使用控件模板 -->
            <Button Template="{StaticResource MyButtonTemplate}" Content="Button 1" Width="100" Height="50"/>
            <Button Template="{StaticResource MyButtonTemplate}" Content="Button 2" Width="100" Height="50"/>
            <Label Template="{StaticResource LabelTemplate }" Content="123" Width="100" Height="40"/>
            <!--这样-->
            <ListBox ItemTemplate="{StaticResource StaffDataTemplate}" ItemsSource="{Binding  People}">
            </ListBox>
            <!--或者这样-->
            <StackPanel>
                <ListBox ItemsSource="{Binding People}" ItemTemplate="{StaticResource StaffDataTemplate}"/>
            </StackPanel>

        </StackPanel>
    </Grid>
</Window>

运行效果

3. 基于模板的样式 StylewithTemplates

3.1 在资源字典中定义一个样式

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    
    <!--定义样式-->
    <Style x:Key="MyButtonStyle" TargetType="Button">
        <Setter Property="Background" Value="LightGreen"/>
        <Setter Property="Foreground" Value="White"/>
        <Setter Property="FontWeight" Value="Bold"/>
    </Style>
</ResourceDictionary>

3.2 使用样式

<Window x:Class="Template.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
        Title="{Binding Title}" Height="350" Width="525" >
    <Window.Resources>
        <!-- 引用外部的资源字典 -->
        <ResourceDictionary  Source="ControlTemplates.xaml" />
    </Window.Resources>
    <Grid>
        <StackPanel>
            <!-- 使用样式 -->
            <Button Style="{StaticResource MyButtonStyle}" Content="Button 1" Width="100" Height="50"/>
            <Button Style="{StaticResource MyButtonStyle}" Content="Button 2" Width="100" Height="50"/>
            <Button Style="{StaticResource MyButtonStyle}" Content="Button 3" Width="100" Height="50"/>
            <Button Style="{StaticResource MyButtonStyle}" Content="Button 4" Width="100" Height="50"/>
            
        </StackPanel>
    </Grid>
</Window>

运行效果

4. WPF的模板资源

  • HandyControl:这是一套比较流行的 WPF 控件库,几乎重写了所有原生样式,并且包含 80 余款自定义控件。在其开源项目中,有大量的模板定义和使用案例,对于想要快速构建美观的 WPF 应用程序的开发者来说非常有价值。你可以访问HandyControl 的 GitHub 页面获取相关资源。
  • Panuon.WPF.UI:该组件库能帮助开发者快速完成样式和控件的 UI 设计,提供了大量的属性来方便地修改 WPF 中一些常用的效果,而这些效果的实现往往涉及到模板的使用。你可以在Panuon.WPF.UI 的 GitHub 页面上找到相关的代码和示例。
  • ModernUI:提供了基于 ModernUI 1.0.4 的 win8 极简化界面设计,有丰富的界面组件和样式,支持插件化开发,便于扩展和维护。你可以从ModernUI 的项目地址获取相关资源。

原文地址:https://blog.csdn.net/weixin_46540714/article/details/143821324

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!