【问题标题】:ASP.NET : Possible to create a UserControl that include inside markup content?ASP.NET:可以创建包含内部标记内容的用户控件吗?
【发布时间】:2009-02-13 07:08:29
【问题描述】:

我正在尝试实现一些谷歌无法给出答案的事情。我正在尝试创建一个 asp.net 用户控件,当我将内容放入其中时,它的打开关闭标签将包含它,以便我仍然能够通过父 ID 访问它的内容。这是我想要实现的一个示例。

用户控制:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ctrlGENE_CollapsiblePanel.ascx.cs"
    Inherits="Controls_GenericsControls_ctrlGENE_CollapsiblePanel" %>
<asp:Panel ID="pnlHeader" CssClass="SnapPanelHeader" runat="server">
    <h3>
        <asp:Literal ID="litTitle" Text='<%# Text %>' runat="server" />
    </h3>
    <div class="SnapPanelHeader-img">
        <img id="imgOpenClose" src="/images/application/close.jpg" alt="" />
    </div>
</asp:Panel>
<asp:PlaceHolder runat="server" ID="pnlContent">
// **HERE I WANT TO INCLUDE THE INSIDE MARKUP**
</asp:PlaceHolder>
<act:CollapsiblePanelExtender runat="server" TargetControlID="pnlContent" ImageControlID="imgOpenClose"
    ExpandControlID="imgOpenClose" CollapseControlID="imgOpenClose" CollapsedImage="/images/application/open.jpg"
    ExpandedImage="/images/application/close.jpg" CollapsedSize="0" TextLabelID="litTitle">
</act:CollapsiblePanelExtender>

包含控件的父页面:

<uc:MyUserControl ID="clpTest" runat="server">
     <asp:Literal ID="litText" runat="server" />
</uc:MyUserControl>

这样我就可以在 Parent.cs 文件中做:

litText.Text = "Anything";

我知道我们可以实现与 ITemplate 接口类似的东西,如下所示:http://msdn.microsoft.com/en-us/library/36574bf6.aspx

看起来像这样:

<uc:MyUserControl ID="clpTest" runat="server">
     <ItemTemplate>
          <asp:Literal ID="litText" runat="server" />
     </ItemTemplate>
</uc:MyUserControl>

但如果我这样做,我将无法访问 litText 的属性,而我可以访问它的唯一方法是使用 FindControl,我想避免这种情况。

如果我能以一种或另一种方式达到我的目标,有人对此有提示吗?

谢谢

【问题讨论】:

  • 最终目标是什么?这个解决方案可能对你需要的来说太复杂了

标签: c# asp.net user-controls


【解决方案1】:

好的,我在这里修复它是我使用的解决方案:

在 MyUserConstrol.ascx 文件中,我在希望显示 innerHTML 的位置放置了一个占位符:

<asp:PlaceHolder runat="server" ID="plhContent" />

然后在 MyUserControl.ascx.cs 文件中,我将这些属性添加到类中:

[ParseChildren(false)]
[PersistChildren(true)]

我在文件中添加了这个:

public void RegisterUpdatePanel(UpdatePanel panel)
{
    MethodInfo m =
        (from methods in typeof (ScriptManager).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
         where methods.Name.Equals("System.Web.UI.IScriptManagerInternal.RegisterUpdatePanel")
         select methods).First();

    m.Invoke(ScriptManager.GetCurrent(Page), new object[] {panel});
}

protected override void CreateChildControls()
{
    for (int i = 0; i < Controls.Count; i++)
        if (Controls[i] is MyLastControl)
            while (i + 2 < Controls.Count)
            {
                // In cas there is an updatepanel in the control we are moving
                // We are registering an event to register the updatepanel
                // to the scriptmanager again
                SearchUpdatePanel(Controls[i + 2]);
                plhContent.Controls.Add(Controls[i + 2]);
            }
    base.CreateChildControls();
}

private void SearchUpdatePanel(Control control)
{
    if (control is UpdatePanel)
        control.Unload += updPnl_Unload;

    foreach (Control childcontrol in control.Controls)
        SearchUpdatePanel(childcontrol);
}

protected void updPnl_Unload(object sender, EventArgs e)
{
    RegisterUpdatePanel((UpdatePanel) sender);
}

请注意,我将我在 ascx 文件中的最后一个控件命名为 myLastContol 以了解在 innerHTML 注入之前的控件是什么,因为我不知道我收到了什么。该过程基本上是在UserControl中的控件中循环,当您到达UserControl的末尾时,之后的所有内容都是来自父级的innerHTML,因此将它们移动到我想要它们的占位符。

我希望这会对某人有所帮助。

以下是我用来实现目标的一些资源: Registering UpdatePanel

【讨论】:

    【解决方案2】:

    在用户控件的代码隐藏文件中添加公共属性。如果您需要设计时支持,则需要进行更多工作,但对于您概述的简单场景来说,这应该足够了。

    然后只需在父页面中访问它以设置值并在用户控件中读取它并使用该值在此处呈现您需要的任何内容。

    【讨论】:

      猜你喜欢
      • 2010-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-13
      • 1970-01-01
      • 1970-01-01
      • 2021-10-31
      • 1970-01-01
      相关资源
      最近更新 更多