views:

1440

answers:

2

Hi,

I'm trying to achieve something google isn't able to give answer. I'm trying to create an asp.net usercontrol that when I put content into it's open close tag will include it for me to be still able to acess it's content by ID from the Parent. Here is an exemple of what I want to achieve.

Usercontrol:

<%@ 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>

Parent Page that include control :

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

Like this I would be able in the Parent.cs file to do :

litText.Text = "Anything";

I know we can achieve something similiar with the ITemplate interface as show here : http://msdn.microsoft.com/en-us/library/36574bf6.aspx

That would look like this:

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

But If I do this I wouldn't be able to access the property of litText and the only way I could reach it is with a FindControl, which I want to avoid.

Anyone have a hint on this if I can reach my goal one way or another?

Thank you

A: 

Add a public property in the user control's code behind file. If you need design time support there's more work involved, but for simple scenarios like the one you outlined it should be enough.

Then just access it in the parent page to set the value and read it in the user control and use that value to render whatever you need there.

Pawel Krakowiak
+3  A: 

Ok I fixed it here is the solution I used :

In MyUserConstrol.ascx file I have put a placeholder where I wanted innerHTML to show :

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

Then in the MyUserControl.ascx.cs file I added those attribute to the class:

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

And I added to the file this:

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);
}

Note that I named my last control in the ascx file myLastContol to know what was the control before the innerHTML injection since I don't know what I'm receiving. The the procedure basically say loop in the controls in the UserControl, when you will reach the end of UserControl, everything after is innerHTML from parent so take those and move them to the placeholder where I want them.

I hope this will help someone.

Here is some sources I used to achieve my goal : Registering UpdatePanel

lucian.jp