3

我正在整理一个网站,该网站从数据库中获取内容并将其填充到一个组件中,然后将其加载到页面上。问题是有许多不同的组件在编译时是未知的,我想从数据库中调用它们。

例如,可能有几个组件,例如:

  • 模组内容.ascx
  • modSlidingBanner.ascx
  • modEmailSlug.ascx

并且数据库将包含一个表,其中包含定义要使用的模块和要加载到其中的内容的字段:

  • 模块名称:“模块内容”
  • 内容:“zippidy doo da”

所以让我们说 modContent.ascx 看起来像:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="modContent.ascx.cs" Inherits="modContent" %>

<div class="content">
    <div class="content-wrapper" ID="divContentWrapper" runat="server">
        <asp:Literal ID="litContent" runat="server"></asp:Literal>
    </div>
</div>

而 modContent.ascx.cs 包含方法:

public void FillIn(string html)
{
    litContent.Text = html;
}

在我的主页上,我想加载这个控件并调用 FillIn 方法。如果我事先知道控件类型,我可以轻松做到这一点:

modContent c = LoadControl("~/modContent.aspx");
c.FillIn(ContentFromDatabase);
divTargetPanel.Controls.Add(c);

但是,正如我所提到的,我想根据数据库中的字符串选择几个控件之一。我可以保证这些控件中的每一个都将具有 FillIn 方法。而且我想避免必须有一个大的 switch 子句或每次我添加一个可能使用的新控件时我必须在主页上更改代码的东西。

我可以像这样将一个模块加载到页面上:

Control c = LoadControl("~/" + ControlNameFromDatabase + ".aspx");
divTargetPanel.Controls.Add(c);

但无法调用此控件的 FillIn 方法。

我可以将 FillIn 方法功能移动到 Control 的构造函数并尝试以下操作:

Assembly assembly = typeof(ControlsParentClass).Assembly;
Type type = assembly.GetType(ControlNameFromDatabase);
skinHome.divContentPanel.Controls.Add(LoadControl(type, new object[] { ContentFromDatabase }));

但是,这个错误是因为在 modContent.ascx.cs 中litContent返回null,如这个人的问题中所述。

显然,上述控制非常简单。我已将其简化为基础知识。这些模块实际上要复杂得多,每个模块都有自己的结构和代码,但具有相同的方法名称/参数。

我要这样做是完全错误的吗?

4

1 回答 1

2

声明一个包含所有公共方法和属性的接口

public interface IMyControl
{
  void FillIn(string html);
}

从此界面继承所有控件:

public partial class modContent : Control, IMyControl

将所有控件投射到IMyControl并调用FillIn

IMyControl c = LoadControl("~/modContent.aspx") as IMyControl;
c.FillIn(ContentFromDatabase);
divTargetPanel.Controls.Add(c as Control);
于 2013-05-01T15:18:17.633 回答