Solved

User control to wrap existing code - how to do it?

Posted on 2009-06-29
3
640 Views
Last Modified: 2013-12-26
Hi there,

We have an AJAX enabled .NET web site throughout which we use a customised GridView control. This is a class which is inherited from the standard GridView (System.Web.UI.WebControls.GridView). We would now like to wrap an AJAX Update Panel around each use of this custom GridView.

We could go through each page and insert the appropriate markup for the Update Panel whereever we use our custom web control, but I would like a more elegant (and less time consuming) solution.

I can't just change the existing custom web control, because it isn't an ascx and therefore it has no markup of its own. Similarly, I can't render an AJAX update panel whenever the custom gridview is rendered without doing all the essential AJAX plumbing that goes with it

I thought about a new ascx user control, but I can't find a way to wrap this around existing markup. Am I missing something horribly obvious here?

Any help greatly appreciated.

TIA,

/\/\
0
Comment
Question by:martyn_bannister
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
3 Comments
 
LVL 12

Expert Comment

by:wht1986
ID: 24741208
What you are asking to do is "how to do i create a composite control without creating a composite control" :)

All I can think of is perhaps override the CreateChildControls event.  This is where the server control builds all the internal controls and adds them to its controls collection.

So perhaps, let the grid build its child controls, but then remove them and add them to your own update panel, and then add the update panel back to the controls collection.  Pseudo code below, just thinking off the cuff
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI;
 
public class Class1 : GridView
{
    protected override void CreateChildControls()
    {
        base.CreateChildControls();
 
        UpdatePanel panel = new UpdatePanel();
        panel.ID = "GridUpdatePanel";
 
        while (this.Controls.Count > 0)
        {
            Control C = this.Controls[0];
            this.Controls.RemoveAt(0);
            panel.TemplateControl.Controls.Add(C);
        }
 
        this.Controls.Add(panel);
    }
}

Open in new window

0
 
LVL 12

Expert Comment

by:wht1986
ID: 24741220
and actually i think the correct place to add back is the
    panel.ContentTemplateContainer.Controls.Add(C);
not
    panel.TemplateControl.Controls.Add(C);
0
 
LVL 2

Accepted Solution

by:
martyn_bannister earned 0 total points
ID: 24743308
Hi wht1986,

Thanks for trying to help, but finally tracked down the solution I needed. It is a "Templated Control". This is basically a usercontrol which exposes a property based on the ITemplate interface. This property then allows a consumer of the ASCX to place any markup they want into the template. The ASCX has markup of its own which, in my case, is the UpdatePanel whose content is a a PlaceHolder. In the control's OnInit event, you read  the markup that the consumer has entered and use the "InstantiateIn" method to render it out to the PlaceHolder.

Beauty of this approach is that we can have any markup in and around the update panel in the user control and allow the consumer to place any markup inside the update panel. A further nicety is to expose the UpdatePanel properties (such as the Triggers) to the consumer of our control.

Solution attached, as well as code snippets.

Rgds,

/\/\
''' ASCX Markup
<%@ Control Language="VB" AutoEventWireup="false" CodeFile="RGVUpdatePanel.ascx.vb" Inherits="RGVUpdatePanel" %>
<asp:UpdatePanel ID="RGVUpdatePanel" runat="server">
    <Triggers>
    </Triggers>
    <ContentTemplate>
        <asp:PlaceHolder ID="RGVPlaceHolder" runat="server"></asp:PlaceHolder>
    </ContentTemplate>
</asp:UpdatePanel>
 
''' ASCX.VB code
''' <summary>
''' User control that incorporates an UpdatePanel Control
''' </summary>
''' <remarks></remarks>
<PersistChildren(True)> _
<ParseChildren(True)> _
Partial Class RGVUpdatePanel
    Inherits System.Web.UI.UserControl
 
    ' Storage for user supplied markup
    Private _Content As ITemplate = Nothing
 
    ' Expose the markup storage to consumers of this user control
    <TemplateInstance(TemplateInstance.Single)> _
    <TemplateContainer(GetType(TemplateControl))> _
    <PersistenceMode(PersistenceMode.InnerProperty)> _
    Public Property ContentTemplate() As ITemplate
        Get
            Return _Content
        End Get
        Set(ByVal value As ITemplate)
            _Content = value
        End Set
    End Property
 
    ' Expose the UpdatePanel's Triggers to consumers
    ' of this user control
    ' The attribute makes intellisense aware of this property
    <PersistenceMode(PersistenceMode.InnerProperty)> _
    Public ReadOnly Property Triggers() As UpdatePanelTriggerCollection
        Get
            Return Me.RGVUpdatePanel.Triggers
        End Get
    End Property
 
    ' When this control builds, write out the user supplied markup
    '  into the PlaceHolder inside the UpdatePanel
    Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
        MyBase.OnInit(e)
        If Not (_Content Is Nothing) Then
            _Content.InstantiateIn(Me.RGVPlaceHolder)
        End If
    End Sub
End Class
 
''' ASPX to utilise this control
.....
<%@ Register TagPrefix="uc" TagName="MyUpdatePanel" Src="~/RGVUpdatePanel.ascx" %>
.....
    <uc:MyUpdatePanel ID="Panel1" runat="server">
        <Triggers>
            <asp:AsyncPostBackTrigger ControlID ="Button1" EventName="Click" />
        </Triggers>
        <ContentTemplate>
            <p>
                <asp:Label ID="Label1" runat="server" Text="Label" Width="300px"></asp:Label>
            </p>
        </ContentTemplate>
    </uc:MyUpdatePanel>
....

Open in new window

AJAXUPTest.zip
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

724 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question