wpf-控件绑定自定义样式的方式

方式一:从资源字典中引用样式

可以把样式定义在资源字典文件里,然后在多个窗口或控件中引用。

  1. 创建资源字典文件
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style x:Key="ButtonStyle" TargetType="Button">
        <Setter Property="Background" Value="Orange"/>
        <Setter Property="Foreground" Value="White"/>
    </Style>
</ResourceDictionary>
  1. 引用资源字典

有两种引用方式

  • 一是直接在窗口中引用资源字典配置。
  • 二是把所有的资源字典的引用配置放在 App.xaml 文件的 <Application.Resources> 里,能让应用程序里的所有窗口和控件都能访问这些共享样式,而无需在每个窗口中重复编写资源字典的引用代码。

下面将介绍两种处理方法

方法一:在窗口中引用资源字典

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <!-- 引用资源字典配置 -->
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Styles/ButtonDictionaryStyle.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <!-- 应用资源字典中的样式 -->
        <Button Content="Click Me" Style="{StaticResource ButtonStyle}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</Window>

方式二:在App.xaml文件中存放所有的资源字典配置。

<Application
    x:Class="WpfDemo.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfDemo"
    StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Styles/ButtonDictionaryStyle.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>
<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <!-- 应用资源字典中的样式 -->
        <Button Content="Click Me" Style="{StaticResource ButtonStyle}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</Window>

效果图

方式二:直接在控件上设置样式

直接在 XAML 中为控件设置样式。

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
     <Window.Resources>
        <!-- 定义Button样式 -->
        <Style x:Key="ButtonStyle" TargetType="Button">
             <Setter Property="Background" Value="Orange" />
             <Setter Property="Foreground" Value="White" />
        </Style>
    </Window.Resources>
    <Grid>
        <!-- 应用资源字典中的样式 -->
        <Button Content="Click Me" Style="{StaticResource ButtonStyle}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</Window>

效果图

方法三:使用隐式样式

使用隐式样式会自动应用到指定类型的所有控件上,无需显式引用样式键。

定义Button样式的时候不需要设置x:Key,应用样式的时候也不需要使用Style属性,当前窗口内所有的 Button 控件都会自动应用这个样式。

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
     <Window.Resources>
        <!-- 定义Button样式 -->
        <Style TargetType="Button">
             <Setter Property="Background" Value="Orange" />
             <Setter Property="Foreground" Value="White" />
        </Style>
    </Window.Resources>
    <Grid>
        <!-- 应用资源字典中的样式 -->
        <Button Content="Click Me" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</Window>

效果图

方式四:基于数据绑定动态应用样式

下面将展示根据按钮的 IsEnabled 属性动态改变按钮的背景颜色。

XAML部分

CheckBox 控件勾选或取消勾选时,CheckBox 控件的 IsChecked 属性会根据勾选状态变为 true 或 false,然后自动传递给 ViewModel 里的 IsButtonEnabled 属性并进行更新。

<Window
    x:Class="WpfDemo.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:local="clr-namespace:WpfDemo"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="800"
    Height="450"
    mc:Ignorable="d">
    <Window.Resources>
        <!--  定义正常状态下按钮的样式  -->
        <Style x:Key="NormalButtonStyle" TargetType="Button">
            <Setter Property="Background" Value="Green" />
            <Setter Property="Foreground" Value="White" />
        </Style>
        <!--  定义禁用状态下按钮的样式  -->
        <Style x:Key="DisabledButtonStyle" TargetType="Button">
            <Setter Property="Background" Value="Gray" />
            <Setter Property="Foreground" Value="Black" />
        </Style>
        <!--  定义布尔值到样式的转换器  -->
        <local:ButtonStyleConverter
            x:Key="ButtonStyleConverter"
            FalseStyle="{StaticResource DisabledButtonStyle}"
            TrueStyle="{StaticResource NormalButtonStyle}" />
    </Window.Resources>
    <Grid>
        <StackPanel>
            <!--  绑定到 ViewModel 的 IsButtonEnabled 属性,动态应用样式  -->
            <Button
                Content="点击我"
                IsEnabled="{Binding IsButtonEnabled}"
                Style="{Binding IsButtonEnabled, Converter={StaticResource ButtonStyleConverter}}" />
            <!--  切换按钮状态的复选框  -->
            <CheckBox Content="启用按钮" IsChecked="{Binding IsButtonEnabled}" />
        </StackPanel>
    </Grid>
</Window>

XAML后台

  • MainViewModel 类实现了 INotifyPropertyChanged 接口,包含一个 IsButtonEnabled 属性,用于控制按钮的启用状态,默认初始化是True状态。
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        // 设置窗口的 DataContext 为 ViewModel 实例
        DataContext = new MainViewModel();
    }
}
public class MainViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private bool _isButtonEnabled;
    public bool IsButtonEnabled
    {
        get { return _isButtonEnabled; }
        set
        {
            if (_isButtonEnabled != value)
            {
                _isButtonEnabled = value;
                OnPropertyChanged(nameof(IsButtonEnabled));
            }
        }
    }

    public MainViewModel()
    {
        // 初始化按钮状态
        IsButtonEnabled = true;
    }
}

创建ButtonStyleConverter 转换器类,该类实现了 IValueConverter 接口,根据布尔值返回对应的样式。

 public class ButtonStyleConverter : IValueConverter
 {
     public Style TrueStyle { get; set; }
     public Style FalseStyle { get; set; }

     public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
     {
         if (value is bool boolValue)
         {
             return boolValue ? TrueStyle : FalseStyle;
         }
         return DependencyProperty.UnsetValue;
     }

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
     {
         throw new NotImplementedException();
     }
 }

效果图

默认初始化设置为True状态,对应NormalButtonStyle样式。

取消勾选按钮后,变为False状态,对应DisabledButtonStyle样式。

posted @ 2025-04-01 19:24  相遇就是有缘  阅读(74)  评论(0)    收藏  举报