C# 如何将自己的主题应用于Windows窗体应用程序?

C# 如何将自己的主题应用于Windows窗体应用程序?,c#,.net,winforms,C#,.net,Winforms,在C#中执行应用程序时,窗体的视图看起来与Windows的主题相同 如果我的应用程序不依赖于Windows主题,我如何为它提供自己的主题呢?你不能轻易做到这一点。有几种选择可供你选择 最简单的方法是创建自己的皮肤XML文件,在该文件中为应用程序指定自己的颜色,并通过创建的类读取该文件,然后应用新颜色。这将使事情分开,并为将来的变化做好准备。但是请注意,您仍然无法更改标题栏的呈现方式以及其他特定于系统的内容,例如X和Maximize按钮的外观 展开第1点,您可以创建无边界的窗体,并使用自定义绘制(

在C#中执行应用程序时,窗体的视图看起来与Windows的主题相同


如果我的应用程序不依赖于Windows主题,我如何为它提供自己的主题呢?

你不能轻易做到这一点。有几种选择可供你选择

  • 最简单的方法是创建自己的皮肤XML文件,在该文件中为应用程序指定自己的颜色,并通过创建的类读取该文件,然后应用新颜色。这将使事情分开,并为将来的变化做好准备。但是请注意,您仍然无法更改标题栏的呈现方式以及其他特定于系统的内容,例如X和Maximize按钮的外观

  • 展开第1点,您可以创建无边界的窗体,并使用自定义绘制(覆盖OnPaint)和图像创建窗口。这是很难做到的。您可能希望从Form类继承并创建自己的CustomDrawnForm,以便在整个应用程序中使用

  • 使用许多控制库中的一个,例如DevExpress。有些是免费的,有些是昂贵的


  • 您尝试在Windows.Forms中执行的操作不是很简单,也许您应该看看WPF和其他替代方法。

    重写
    OnPaint
    方法并绘制您想要的任何东西。:)


    这取决于你的主题意图;正如Hans在评论中所说,通常将系统的“主题”用于控件和窗口外观被视为一种资产

    但是,要在应用程序中对元素进行主题化,例如标题面板的背景或标题字体颜色等。然后,我将为应用程序中的颜色/图像创建一个带有定义的界面(例如,
    ITheme
    )然后,只要在运行时设置
    ITheme
    时使用常规数据绑定来适当配置它们

    public interface ITheme
    {
        string Name { get; }
        Image Logo { get; }
        String BrandText1 { get; }
        String BrandText2 { get; }
        Image BrandBannerLogo { get; }
        Color BrandPanelText_Left { get; }
        Color BrandPanelText_Centre { get; }
    }
    
    事实上,你可以更进一步。。。例如,在我们的应用程序中,我们还定义了一个
    IThemeManager

    public interface IThemeManager : INotifyPropertyChanged
    {
        event EventHandler CurrentThemeChanged;
        ITheme CurrentTheme { get; set; }
        Dictionary<string, ITheme> AvailableThemes { get; }
    }
    

    我知道这个问题已经很老了,但是对于那些(像我一样)仍然对创建真正的“主题化”Windows窗体感兴趣的人来说,如上所述,WPF非常适合创建主题。还有很多预先创建的主题可供下载(谷歌和stackoverflow永远是你的朋友)。从Windows窗体项目世界可能会有一点学习曲线,但我认为这是值得的。但是,如果您希望继续使用普通的Windows窗体应用程序(如我所做的),最简单的建议是创建无边框窗体(将FormBorderStyle设置为None)。这将维护大多数标准windows容器属性。当然,您需要创建自己的“主题”标题栏和边框,但这主要是Windows窗体的“主题”所在。您还需要创建自己的大小调整和移动方法,但同样,Google和stackoverflow是您的朋友。这个简单的建议对某些人来说很明显,但对我来说却很重要。

    您是否尝试过从主程序中删除对EnableVisualStyles()的调用?是的,但它只提供了经典样式使您的UI与用户选择的主题相似,这被广泛认为是一种资产,而不是负债。它需要像Adobe和Microsoft这样的大公司的资源来不断更新他们的自定义皮肤代码,以防止它变得陈旧和愚蠢。看看这个:
    public interface IThemeManager : INotifyPropertyChanged
    {
        event EventHandler CurrentThemeChanged;
        ITheme CurrentTheme { get; set; }
        Dictionary<string, ITheme> AvailableThemes { get; }
    }
    
        [Dependency]
        public IThemeManager ThemeManager
        {
            get { return _themeManager; }
            set
            {
                if (_themeManager != value)
                {
                    _themeManager = value;
                    if (_themeManager != null && !DesignMode)
                    {
                        _headerPanelBackgroundImageBinding = themePanel.DataBindings.Add("BackgroundImage", ThemeManager, "CuurentTheme.Logo", false, DataSourceUpdateMode.Never);
                    }
                    else
                    {
                        // Reset to the default
                        this.DataBindings.Remove(_headerPanelBackgroundImageBinding);
                    }
    
                    Invalidate();
                }
            }
        }