You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在WPF应用中全局切换自定义样式与MaterialDesign样式(支持运行时)

全局切换WPF样式(自定义↔MaterialDesign)的可行方案

方案1:动态切换全局资源字典(推荐,支持运行时切换)

这种方式通过修改应用的全局资源字典集合,实现所有控件样式的批量切换,无需逐个控件绑定配置。

步骤:

  1. 拆分样式资源

    • 将自定义样式整理到独立的CustomStyles.xaml资源字典:
      <!-- CustomStyles.xaml -->
      <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
          <Style x:Key="CustomButtonStyle" TargetType="Button">
              <!-- 你的自定义按钮样式定义 -->
          </Style>
          <!-- 其他控件的自定义样式 -->
      </ResourceDictionary>
      
    • 封装MaterialDesign资源到MaterialDesignStyles.xaml(方便统一管理):
      <!-- MaterialDesignStyles.xaml -->
      <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
          <ResourceDictionary.MergedDictionaries>
              <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Default.xaml"/>
              <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml"/>
              <!-- 按需添加其他MaterialDesign主题资源 -->
          </ResourceDictionary.MergedDictionaries>
      </ResourceDictionary>
      
  2. 初始化应用资源
    在App.xaml中默认加载一套样式(比如自定义样式),预留资源字典集合用于动态修改:

    <!-- App.xaml -->
    <Application x:Class="YourAppName.App"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <Application.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <!-- 默认加载自定义样式 -->
                    <ResourceDictionary x:Name="CurrentStyleDict" Source="CustomStyles.xaml"/>
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </Application.Resources>
    </Application>
    
  3. 实现运行时切换逻辑
    在后台代码(如App.xaml.cs或专门的样式管理类)中编写切换方法:

    public void SwitchToMaterialDesign()
    {
        var appResources = Application.Current.Resources.MergedDictionaries;
        // 移除当前自定义样式字典
        var customDict = appResources.FirstOrDefault(d => d.Source?.OriginalString.Contains("CustomStyles") ?? false);
        if (customDict != null) appResources.Remove(customDict);
        // 添加MaterialDesign样式字典
        var mdDict = new ResourceDictionary { Source = new Uri("MaterialDesignStyles.xaml", UriKind.Relative) };
        appResources.Add(mdDict);
    }
    
    public void SwitchToCustomStyle()
    {
        var appResources = Application.Current.Resources.MergedDictionaries;
        // 移除MaterialDesign样式字典
        var mdDict = appResources.FirstOrDefault(d => d.Source?.OriginalString.Contains("MaterialDesignStyles") ?? false);
        if (mdDict != null) appResources.Remove(mdDict);
        // 添加自定义样式字典
        var customDict = new ResourceDictionary { Source = new Uri("CustomStyles.xaml", UriKind.Relative) };
        appResources.Add(customDict);
    }
    

    调用时直接在按钮点击事件中执行SwitchToMaterialDesign()或SwitchToCustomStyle(),所有使用全局样式的控件会自动更新。

方案2:绑定全局动态样式键(适合精细化控制)

如果需要保留部分控件的独立样式,同时全局切换大部分控件样式,可以定义统一的动态资源键,让目标控件绑定该键,再通过修改资源字典中键的对应值实现切换。

步骤:

  1. 定义全局样式键
    在App.xaml中定义动态资源键,默认指向自定义样式:

    <!-- App.xaml -->
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="CustomStyles.xaml"/>
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Default.xaml"/>
            </ResourceDictionary.MergedDictionaries>
            <!-- 全局按钮样式键,默认绑定自定义样式 -->
            <Style x:Key="GlobalButtonStyle" BasedOn="{StaticResource CustomButtonStyle}" TargetType="Button"/>
            <!-- 其他控件的全局样式键 -->
        </ResourceDictionary>
    </Application.Resources>
    
  2. 所有目标控件绑定全局样式键
    在窗口/页面中,统一使用全局样式键:

    <Button Style="{DynamicResource GlobalButtonStyle}" Content="测试按钮"/>
    
  3. 运行时切换样式
    通过修改全局键的BasedOn属性实现切换:

    public void ToggleButtonStyle(bool useMaterialDesign)
    {
        var globalStyle = Application.Current.Resources["GlobalButtonStyle"] as Style;
        if (globalStyle == null) return;
    
        globalStyle.BasedOn = useMaterialDesign 
            ? Application.Current.Resources["MaterialDesignFlatAccentBgButton"] as Style 
            : Application.Current.Resources["CustomButtonStyle"] as Style;
        
        // 强制更新所有绑定该样式的控件
        foreach (Window window in Application.Current.Windows)
        {
            window.UpdateLayout();
        }
    }
    

方案3:让MaterialDesign样式默认覆盖自定义样式

如果不需要运行时切换,仅希望加载MaterialDesign时自动覆盖自定义样式,只需调整资源字典的加载顺序:后加载的资源字典会覆盖先加载的同名样式。

修改App.xaml,将MaterialDesign资源字典放在自定义样式之后:

<!-- App.xaml -->
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <!-- 先加载自定义样式 -->
            <ResourceDictionary Source="CustomStyles.xaml"/>
            <!-- 后加载MaterialDesign样式,覆盖同名样式 -->
            <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Default.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

这样,当两个资源字典存在同名样式键时,MaterialDesign的样式会优先生效。


内容的提问来源于stack exchange,提问作者Othmane Ouazzani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 22:45:58