动态生成窗体控件

时间:2016-09-27 19:47:38

标签: c# winforms user-interface design-patterns factory-pattern

我正在尝试使用抽象工厂模式创建一个带有可自定义“主题”的表单应用程序(只是为了获得一些经验)。我创建了一个像这样的主题工厂的实现:

public class BlueTheme : IThemeFactory
{
    public Button CreateButton() => new BlueButton();
    // ... more controls here ...
}

现在我通过IThemeFactory的构造函数传递Form实例:

private IThemeFactory _themeFactory;

public Form1(IThemeFactory theme)
{
    _themeFactory = theme; // e.g. new BlueTheme()
    InitializeComponent();
}

我的问题是:是否有办法让我的表单使用IThemeFactory.CreateButton()方法生成表单上的所有按钮?

2 个答案:

答案 0 :(得分:0)

尽管由Windows窗体设计器创建,但InitializeComponent()方法完全正常且可以编辑。它位于文件中:*.Designer.cs(其中*是您班级的名称)。

该方法包含组件的所有构造函数调用,但您可以继续使用工厂方法调用替换它们。请注意,这可能会阻止您使用Windows窗体设计器编辑布局,但您可以在设计器中执行的所有操作都可以通过编辑*.Designer.cs*文件中的代码来完成。

答案 1 :(得分:0)

由于似乎不可能使用工厂来实现我尝试做的事情,所以我决定通过递归循环来对现有组件进行样式化:

public abstract class Theme
{
    public delegate void ButtonStyler(Button button);
    public ButtonStyler StyleButton { get; }

    protected Theme(ButtonStyler styleButton)
    {
        StyleButton = styleButton;
    }

    // Apply this theme to all components recursively
    public void Style(Control parent)
    {
        if (parent is Button) StyleButton((Button) parent);
        foreach (Control child in parent.Controls) Style(child);
    }
}

public class BlueTheme : Theme
{
    public BlueTheme() : base(
        button =>
        {
            button.BackColor = Color.DeepSkyBlue;
            button.ForeColor = Color.White;
            button.FlatStyle = FlatStyle.Flat;
        }) {}
}

在这个例子中,我只实现了按钮,但是可以轻松添加任何组件样式,并且使用主题非常简单:

public Form1(Theme theme)
{
    InitializeComponent();
    theme.Style(this);
}

private static void Main() {
    Application.Run(new Form1(new RedTheme()));
}

虽然这有效,但我仍然很好奇这是否可以通过工厂实现,如初始问题中所述。