我正在尝试使用抽象工厂模式创建一个带有可自定义“主题”的表单应用程序(只是为了获得一些经验)。我创建了一个像这样的主题工厂的实现:
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()
方法生成表单上的所有按钮?
答案 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()));
}
虽然这有效,但我仍然很好奇这是否可以通过工厂实现,如初始问题中所述。