如何在C#中为窗体中的控件创建主题选项 [英] How to create a theme option for controls in windows form in C#

查看:123
本文介绍了如何在C#中为窗体中的控件创建主题选项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的表单上有各种控件,包括按钮,单选按钮,文本框和datagridview。有很多形式。



我想为用户提供改变这些控件(包括表格)的颜色主题的工具。

例如,如果用户选择黑色主题选项,则所有控件的背景颜色必须设置为黑色。如果是蓝色,则控件必须具有蓝色背景。



完成此任务的一种方法是我可以为手动颜色的按钮创建用户控件。但这会产生问题。调试后,控件现在受限于代码文件中的特定颜色集。因此,用户无法从一个主题切换到另一个主题。



我想到的另一种方法是创建一个具有不同定义的视觉效果(颜色,字体等)的类控件然后为每个窗体上的每个控件单独引用该类的控件属性。这将是一项非常漫长而艰巨的任务。



我需要一个更简单方法的指导,以便我可以提供这样的设施。

如果对这个问题有任何疑惑,请告诉我。



我尝试了什么:



尝试为特定主题创建用户定义的控件,但它不是解决方案。

There are various controls including buttons, radio buttons, textboxes and datagridview on my form. There are many forms.

I want to provide a facility to the user for changing color theme for these controls including the forms.
For e.g., if user chooses a Black theme option, all controls must have background color set to black. If Blue, then controls must be having blue background.

One way to accomplish this task is I can create a User Control for a button with manual color. But this creates a problem. After debugging the control is now bounded to a specific color set in code file. Thus, user can not switch from one theme to another.

Another way I thought of is to create a class with different defined visuals (colors, font, etc) for controls and then reference the properties of the controls to that class, individually, for each control on each form. This will be very lengthy and tough task to execute.

I need a guidance to a more simple approach, so that I can provide such facility.
Let me know if there are any confusions regarding this question.

What I have tried:

Tried creating user defined controls for specific themes, but its not the solution.

推荐答案

这是一个粗略的骨架 WinForms的样式管理器的开头可能如下所示:
Here's a rough "skeleton" of what the beginnings of a style manager for WinForms might look like:
public static class VisualStyleManager
{
   public static Dictionary<string, VisualStyle> StyleDictionary { set; get; }

   public static void AddStyle(string name, Control control)
   {
        StyleDictionary.Add(name, new VisualStyle(control));
   }
 
   public static void ApplyStyle(string stylename, Control control)
   {
       VisualStyle style;

       if(StyleDictionary.TryGetValue(stylename, out vs)
       {
           control.BackColor = vs.BackColor;
           control ForeColor = vs.ForeColor;
           control.Font = vs.Font;
       }     
   }
}

public class VisualStyle
{
    public Color CBackColor { set; get; }
    public Color CForeColor { set; get; }

    public Font CFont {set; get; }

    public VisualStyle(Control control)
    {
        CBackColor = control.BackColor;
        CForeColor = control.ForeColor;
        CFont = control.Font;
    }
}

以下是它的使用方法:

private void SetAllFormButtons(Form form, button abutton)
{
   VisualStyleManager.AddStyle("ButtonStyle1", button1);

   foreach (var btn in this.GetControlsByType<Button>())
   {
       if (btn != button1)
       {
           VisualStyleManager.ApplyStyle("ButtonStyle1", btn);
       }
   }
}

这使用扩展方法:

public static class ControlExtensions
{
    public static IEnumerable<Control> GetControlsByType<T>(this Control control)
    {
        Stack<Control> stack = new Stack<Control>();

        stack.Push(control);

        while (stack.Any())
        {
            Control nextcontrol = stack.Pop();

            foreach (Control childControl in nextcontrol.Controls)
            {
                stack.Push(childControl);
            }

            if (nextcontrol is T) yield return nextcontrol;
        }
    }
}

现在考虑一下你要处理什么来处理WinForm控件属性,如Form的'FormBorderStyle,或Button的FlatStyle和FlatAppearance属性;当您将这些控件转换为其控件基类型时,这些属性不会公开。



对于每个唯一的控件类型的属性,您必须将其作为特殊情况处理。但是,还有其他方法,大量使用反思来做到这一点。而且,你可以把这里的骨架和子类VisualStyle用特殊要求处理其他控件类型。



到现在为止,你可能已经想通了要获得与主题相关的任何实质性内容涉及(可能)你需要做很多工作。虽然这样做可能会提高您的设计技巧和WinForms内部知识,但如果您处于研究和使用WinForms和C#的相对早期阶段,我建议您不要尝试编写功能齐全的主题设施。



您可以采取其他策略:例如,在运行时显示属性浏览器以让用户编辑颜色,字体等。假设User1编辑了BackColor任何一个按钮;您可以获得该事件的通知,然后将所有其他按钮设置为使用相同的BackColor。

Now consider what you are going to have to deal with to make this handle WinForm Control Properties like a Form's 'FormBorderStyle, or a Button's FlatStyle, and FlatAppearance Properties; these Properties are not exposed when you cast these Controls to their Control base Type.

For every unique Control Type's Property, you will have to handle that as a special case. However, there are other ways, making heavy use of 'Reflection, to do this. And, you can take the "skeleton" here and sub-class VisualStyle to handle other Control Types with "special requirements."

By now, you may have figured out that to get anything substantial going with theming involves (probably) a lot of work on your part. While doing this may improve your design skills and knowledge of WinForms internals, if you are at a relatively early phase in studying and using WinForms and C#, I suggest you do not take on trying to write a full-featured theme facility.

There are other strategies you could pursue: such as, displaying a Property Browser at run-time to let the user edit colors, fonts, etc. Let's say User1 edited the BackColor of any one Button; you could get a notification of that event and then set all the other Buttons to use that same BackColor.


请参阅 windows主题C# - Google搜索 [ ^ ]


如果你想为winforms使用皮肤,请看看这些:



Ye Olde GroupBox的新皮肤 [ ^ ]



石斑鱼 - 自定义组框控件 [ ^ ]



Windows Forms .NET的GUI外观系统 [ ^ <这是一个例子:

If you want to use skinning for winforms take a look at these:

A New Skin for Ye Olde GroupBox[^]

The Grouper - A Custom Groupbox Control[^]

GUI Skinning System for Windows Forms .NET[^]

As suggested by Richard you can iterate through the Control collection, here is an example:
/// <summary>
/// Get the text for Form controls from Resource1
/// </summary>
private void TranslateForm()
{
    string formName = this.Name + "_";
    string str;
 
    foreach (Control ctrl in this.Controls)
    {
        System.Diagnostics.Debug.Print(formName + ctrl.Name);
        System.Diagnostics.Debug.Print(ctrl.GetType().ToString());          // e.g. System.Windows.Forms.Label
        try
        {
            str = Resource1.ResourceManager.GetString(formName + ctrl.Name);        // Form1_lblAddress etc.
            ctrl.Text = str;
        }
        catch (Exception)
        {
            Debug.Print(".");
        }
    }
}


这篇关于如何在C#中为窗体中的控件创建主题选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆