1

我有一个抽象类,用于派生许多其他类,每个类都做类似但略有不同的事情。这些类由反射加载并暴露给用户,以选择他需要运行的类。

这是因为基类有一个名为 Run 的抽象方法,它被每个派生类覆盖。因此,在代码中我需要任何这些类型的变量的任何地方,我都将它们声明为基类。然后当我调用 Run 方法时,它会从真实类型执行该方法(即使我将它声明为基类)。

我的问题是我需要为每个派生类显示一个定制的 UI。我想为每个自定义 UserControl。这些控件将有一个 puclic 方法,该方法根据用户对其所做的操作返回一个值。然后我在运行时创建这个控件,用户设置需要什么,我从这个控件调用 return 方法,最后我可以从用户选择的类中将 i 传递给 Run Run 方法并执行它。

我不知道我有多少或哪些派生类,因为用户可以创建从该基类派生的 dll 并将其作为插件附加。

因此,我认为我必须在表单上创建这些自定义控件作为通用 UserControl 类,然后将它们转换为真实类型。但是只有知道控件是从 UserControl 派生的,有没有办法做到这一点?

我可以在基类上创建一个公共属性来存储其自定义控件,但是回到主代码中,我可以将通用用户控件转换为存储在此属性中的类型吗?

另外,这里会是设计问题吗?我可以使用其他方法来做到这一点吗?

我希望这听起来不会很混乱:(

4

3 回答 3

3

我可能误解了你,但这是我的想法:

public abstract class BaseClass<T> where T: UserControl, IMyControl
{
    private Page _page;
    protected T Control { get; private set;}

    public BaseClass(Page page, string controlPath)
    {
        _page = page;
        Control = (T)page.LoadControl(controlPath);
        _page.Controls.Add(Control);
    }

    public void Run()
    {
        var data = Control.GetData();
    }
}

public interface IMyControl
{
    object GetData();
}
于 2012-04-26T19:27:02.413 回答
1

我将创建一个继承自 UserControl 的类。我认为您不能将其设为抽象,但您可以在其他类型上创建一个名为 CreateControl() 的方法,该方法将返回应该包含 UI 的 UserControl 的实例。

然后,您可以将该 UserControl 添加到 Panel 或其他容器中,而无需真正关心它是什么特定的 UserControl。如果您希望有特定的方法来实现该 UserControl,例如 Save 或 Load,那么您可以将它们作为虚拟方法添加到派生自 UserControl 的 Base 类中。

于 2012-04-26T19:33:54.017 回答
0

我不知道这是否是正确或最佳的解决方案,但基于上述答案和一些研究,我以这种方式解决了问题:

从 BaseClass 派生的每个类都有一个可覆盖的方法 GetControl。此方法返回专门为该类设计的 UserControl 的新实例。

当用户选择派生类时,我调用 GetControl 方法并将此控件添加到表单中。然后显示为该类设计的 UI。如果选择了另一个类并且随后为该其他类创建了新 UI,则删除此控件。

为了读取用户在控件中所做的设置,我在每个 UserControl 上实现了一个名为 ReadData 的方法。要从对象级别调用此方法,我使用了反射:

Object ui = FindControlByName("SelectedClassUI");
Type t = ui.GetType();
MethodInfo m = t.GetMethod("ReadData");
Object userSetup = m.Invoke(ui, null);

<... do something with userSetup ...>
于 2012-05-07T13:50:10.787 回答