【问题标题】:Is it possible to output web control via data binding expression inside ASP.NET server control template?是否可以通过 ASP.NET 服务器控件模板中的数据绑定表达式输出 Web 控件?
【发布时间】:2011-12-19 13:10:34
【问题描述】:

我在整个互联网上搜索这个,包括这里,现在 2 天,但我找不到任何类似的处理。另外,这是我在 Stack Overflow 上的第一篇文章,请多多包涵:]

问题:

这是我第一次实际创建模板化服务器控件,但我在 MSDN 关于模板化主题的帮助下毫无问题地完成了这项工作。我已经实现了一个可以像这样使用的控件:

<test:TemplatedControl ID="templatedControl" runat="server">
    <Template>
        Template start:
        <%# Container.EmailText %>
        <%# Container.EmailField %>
        Template end.
    </Template>
</test:TemplatedControl>

该控件为模板使用以下容器/上下文:

public class TemplateContainer : WebControl, INamingContainer
{
    public string EmailText
    {
        get
        {
            return this.emailLabelText;
        }
    }
    string emailLabelText;


    public TextBox EmailField
    {
        get
        {
            return this.emailField;
        }
    }
    TextBox emailField;


    public TemplateContainer()
        : base(HtmlTextWriterTag.Div)
    {
        this.BorderWidth = 2;
        this.BorderStyle = BorderStyle.Outset;

        this.emailLabelText = "E-mail:";

        this.emailField = new TextBox();
        this.emailField.MaxLength = 10;
    }
}

容器类的两个属性都可以正常工作,并且可以在编写模板时通过数据绑定表达式访问,但是 EmailField 被呈现为 System.Web.UI.WebControls.TextBox,这在给定的代码中是可以的。控件的输出为:

<div style="border-width:2px;border-style:Outset;">
    Template start:
    E-mail:
    System.Web.UI.WebControls.TextBox
    Template end.
</div>

现在的问题是:是否可以通过绑定表达式将控件(例如此处的TextBox)作为实际控件作为其他数据输出回模板中?

如果这可行,那么就可以分离该控件的输出,包括其子控件,并通过模板根据需要将它们组合在一起。

恐怕这根本不可能实现,但我希望有人能澄清这一点。如果是这样的话,我也愿意接受另一种方法的建议。如果您对我为什么要这样做感兴趣,请阅读下文。

采用这种方法的原因:

我正在构建一个复合服务器控件,客户自己将在他的网站上使用该控件,该控件仍在开发中。因此,控件输出的最终布局和格式化需求尚不清楚。相反,控件需要在布局和设计方面具有灵活的输出,以便以后可以对其进行自定义以匹配站点。

这部分的设计部分可以通过给控件设置一些CSS类属性来实现,虽然为客户配置可能会很麻烦,因为控件的输出会相当复杂。

我不确定如何实现可定制的布局要求,例如,在表格结构中呈现表单字段,或者在 div 中呈现它,或者可能只是内联而不需要额外的 HTML,等等。

因此,我没有提供几种预制类型的输出,而是想到了一个想法,即我的控件呈现的输出可以模板化,这可以解决布局和设计灵活性问题。客户将声明性地设置一个模板来包装我的模板需要呈现的内容,这也将使他能够在那里设置他的所有 CSS 类以根据需要包装元素。这让我想到了前面提到的问题。

提前致谢,

加金

【问题讨论】:

  • 您的代码与:&lt;test:TemplatedControl ID="templatedControl" runat="server"&gt; &lt;Template&gt; Template start: &lt;%# Container.EmailText %&gt; &lt;asp:TextBox ID="emailField" runat="server" /&gt; Template end. &lt;/Template&gt; &lt;/test:TemplatedControl&gt; 有何不同
  • 我想保留对这些控件的控制权,因为稍后我需要在我的服务器控件中使用它们。我需要知道哪个字段是哪个,ID 等等。它们一起代表一种特定的形式。我只想让这个服务器控件的使用者能够通过模板决定这些控件的位置。有了这些假设,我可能已经走错路了。
  • 服务器控件的使用者将如何确定这些控件的位置?他们是在 ASP.NET 中开发的吗?
  • 是的,他们将使用正在开发中的 ASP.NET 网站内的控件。因此,他们希望能够根据届时网站的结构来定制样式和 HTML 布局。

标签: asp.net custom-server-controls servercontrols


【解决方案1】:

我认为您需要一个抽象类来定义TemplateContainer 需要具备的内容。例如:

public abstract class TemplateContainer : WebControl, INamingContainer
{
    public abstract Literal EmailText { get; }
    public abstract TextBox EmailField { get; }
}

然后要求test:TemplateControlTemplate实现TemplateContainer

这样你可以使用EmailTextEmailField来申请MaxLength等。虽然你可能想在使用它们之前验证它们不是null

if(EmailText != null)
{
    //use EmailText
}

然后,服务器控件的使用者将创建一个类似于此的控件UserTemplate.ascx

Template start:
<asp:Literal ID="emailText" runat="server" />
<asp:TextBox ID="emailField" runat="server" />
Template end.

UserTemplate.ascx.cs后面有代码:

public class UserTemplate : TemplateContainer
{
    public Literal EmailText { get { return emailText; } }
    public TextBox EmailField { get { return emailField; } }
}

----编辑----

基于所有这些,包含test:TemplatedControl 的页面将如下所示(假设UserTemplate.ascx 的路径别名为test:UserTemplate):

<test:TemplatedControl ID="templatedControl" runat="server">
    <Template>
        <test:UserTemplate ID="userTemplate" runat="server" />
    </Template>
</test:TemplatedControl>

然后在后面的代码中你可以访问UserTemplate上的属性:

templatedControl.Template.EmailText.Text = "Email: ";
templatedControl.Template.EmailField.MaxLength = 10;

【讨论】:

  • 我明白了这一点,我喜欢这种方法。这将使我能够实现我的目标。不过我还有一个小问题。您能否进一步详细说明如何将UserTemplate 与页面上声明的控件连接起来?您打算如何使用 UserTemplate 类?
  • UserTemplate.ascx - 包含“模板开始:”到“模板结束”。我的答案中的代码。 UserTemplate.ascx.cs 包含在我的回答中描述为“代码隐藏”的代码。信息够不够?
  • 这让我走上了正轨,谢谢。很抱歉回答晚了,我想在接受答案之前从大局中看到一切正常,但我不得不将项目推迟一段时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-12
相关资源
最近更新 更多