Solved

Use of delegates in ASP.NET user controls

Posted on 2010-11-11
16
475 Views
Last Modified: 2012-05-10
Dear Experts,

I have a "save" button on an ASP.net web user control which saves some form data.

Within this control is another user control, designed to navigate through records.

When the user presses on a button on the nested user control, I'd like the "save" method on the first ASCX to be called, thus saving the form data before traversing to the next record.

I understand that I'll probably need to use delegates to achieve this, however am would appreciate it if somebody could give me some clarification or advice on how to achieve this.

My navigation buttons on my nested control are hyperlinks which have URLs generated by some business logic.

Any advice would be appreciated.

Nick
0
Comment
Question by:nkewney
[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
  • 8
  • 6
  • 2
16 Comments
 
LVL 18

Expert Comment

by:Richard Lee
ID: 34110611
A simplier approach would be something like this:

DaTribe
public interface ISave
{
   void Save();
}

// This is the page which holds the user control
public class ParentPage : System.Web.UI.Page, ISave
{
}

// This is the usercontrol
public class InnerControl : System.Web.UI.UserControl
{
    public void ButtonClick(object sender, EventArgs e)
    {
        if(Parent is ISave)
        {
            var parent = Parent as ISave;
            parent.Save();

            // Do something else
        }
    }
}

Open in new window

0
 
LVL 1

Author Comment

by:nkewney
ID: 34110648
Hi DaTribe,

Thanks for the tip.

Since it's two user controls, how would this work?

--> I now have this on the control with "save" method

    Public Interface ISave
        Sub EditLead()
    End Interface

I'm just unclear on where to implement this interface?

Nick
0
 
LVL 18

Expert Comment

by:Richard Lee
ID: 34110763
Ok lets try again, follow closely ;)

DaTribe
public interface ISave
{
   void Save();
}

public interface IParentPage
{
   ISave SaveControl { get; }
}


// This is the page which holds the user control
public class ParentPage : System.Web.UI.Page, IParentPage
{
   public ISave SaveControl 
   {
      // This returns the actual usercontrol but 
      // restricts access to the interface methods
      get { return SaveUserControl as ISave; } 
   }
}

// This is the usercontrol with save button
public class SaveUserControl : System.Web.UI.UserControl, ISave
{
   public void Save()
   {
   }
}

// This is the usercontrol with grid
public class GridUserControl : System.Web.UI.UserControl
{
    public void ButtonClick(object sender, EventArgs e)
    {
        if(Parent is IParentPage)
        {
            var parent = Parent as IParentPage;

            if(parent.SaveController != null)
               parent.SaveController.Save();

            // Do something else
        }
    }
}

Open in new window

0
Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

 
LVL 1

Author Comment

by:nkewney
ID: 34111106
Hi DaTribe,

I really appreciate your help, but am slightly confused :)

I'm possibly being completely thick here, but I have three pages:

- Default.aspx (page holding my Profile user control with the "save" method")
- Profile.ascx (holding my navigator user control)
- Navigator.ascx (with the buttons I'd like to control the "save" method on my Profile.ascx)

My understanding is:

Default.aspx
=======================
Public Interface ISave
    Sub Save()
End Interface

Public Interface IParentPage
    ReadOnly Property SaveControl() As ISave
End Interface

Partial Public Class DefaultPage
    Inherits System.Web.UI.Page, IParentPage (can only specify one in class?!)

Nick
0
 
LVL 18

Expert Comment

by:Richard Lee
ID: 34111236
So the referencing mechanism I am trying to achieve in visual form is:

Default.aspx
--------------------------------------
|                                                   |
|       Profile.ascx                            |<-- |
|       ---------------------------      |      | Access parent page and locate Navigator control so we can invoke the Save method
|       |                                    |----|-----
|       |                                    |      |
|       ---------------------------      |
|                                                   |
|       Navigtor.ascx                         |
|       ---------------------------      |
|       |                                    |      |
|       |                                    |----|----> Exposed as a property in default.aspx but restricts access to only features clients are allowed use
|       ---------------------------      |
--------------------------------------

Defauilt.aspx knows about its contents through the normal .NET mechanism. I use interfaces to expose nicely these controls
on the Default.aspx page as properties to anyone who wants to use them and has access to the default.aspx page.

Profile.aspx has access to Default.aspx because it is one of the controls on the page and therefore can get access to the NavigatorControl property and thus can invoke the save method.

The reason for using interfaces is that when exposing properties you want clients to only use what you allow them to, but save yourself the work of recreating a whole other control to do what NavigatorControl is already doing.

DaTribe
public interface ISave
{
   void Save();
}

public interface IDefault
{
   ISave NavigatorControl { get; }
}


// This is the page which holds the user control
public class Default : System.Web.UI.Page, IDefault
{
   public ISave NavigatorControl 
   {
      // This returns the actual usercontrol but 
      // restricts access to the interface methods
      get { return ucNavigator as ISave; } 
   }
}

// This is the usercontrol with save button
public class Navigator: System.Web.UI.UserControl, ISave
{
   public void Save()
   {
   }
}

// This is the usercontrol with grid
public class Profile: System.Web.UI.UserControl
{
    public void ButtonClick(object sender, EventArgs e)
    {
        if(Parent is IDefault)
        {
            var parent = Parent as IDefault;

            if(parent.NavigatorControl != null)
               parent.NavigatorControl.Save();

            // Do something else
        }
    }
}

Open in new window

0
 
LVL 1

Author Comment

by:nkewney
ID: 34111494
Hi DaTribe,

Thanks for your explanation

The navigator is *inside* the Profile control and I think this is where I'm getting confused.

I'm getting there, but could you clarify how it would work in this instance?

Thanks in advance.

Nick
0
 
LVL 18

Expert Comment

by:Richard Lee
ID: 34111637
Here is one solution. Much less complicated that before.

DaTribe
public class Navigator : System.Web.UI.UserControl
{
     public void Save()
     {
     }
}

// To make things really simple you could just
// reference the control directly from the page
// and call its save method
public class Profile: System.Web.UI.UserControl
{
    public void ButtonClick(object sender, EventArgs e)
    {
        ucNavigatorControl.Save();

        // Do something else
    }
}

Open in new window

0
 
LVL 18

Expert Comment

by:Richard Lee
ID: 34111658
Another solution which is slightly more complicated but more controlled.

DaTribe
public interface ISave
{
    void Save();
}

public class Navigator : System.Web.UI.UserControl, ISave
{
     public void Save()
     {
     }
}

// To make things really simple you could just
// reference the control directly from the page
// and call its save method
public class Profile: System.Web.UI.UserControl
{
    public ISave SaveControl
    {
        get { return ucNavigatorControl as ISave; }
    }

    public void ButtonClick(object sender, EventArgs e)
    {
        SaveControl.Save();

        // Do something else
    }
}

Open in new window

0
 
LVL 18

Expert Comment

by:Richard Lee
ID: 34111670
Notice now that the main page is not involved since all needed actions are happening on the two user controls.

DaTribe
0
 
LVL 11

Expert Comment

by:b_levitt
ID: 34111713
I liked your original thought with a delegate/event.  I would define some sort of "SelectedItemChanged" event in your navigation control:

public class NavigatorControl() : UserControl
{
    public event EventHandler SelectedItemChanged;

    //your navigation button handler
    protected void NextItemButton_OnClick(Object sender, EventArgs e)
    {
      //Check for event registrations
      if(SelectedItemChanged != null)
      {
        //passing a reference to the user control itself here with 'this'
        //but it could be a reference to the actual item
        SelectedItemChanged(this, EventArgs.Empty);
      }
    }
}

And then wireup that event in the parent user control:

public class ParentControl : UserControl
{
  protected void Page_Init(Object sender, EventArgs e)
  {
    myNavigatorControl.SelectedItemChanged += new EventHandler(myNavigatorControl_SelectedItemChanged);
  }

  //the handler for the item changed event
  protected void myNavigatorControl_SelectedItemChanged(Object sender, EventArgs e)
  {
     //and your parent level save...
     this.Save();
  }
0
 
LVL 11

Expert Comment

by:b_levitt
ID: 34111742
By the way, this is the article that helped me years ago with events and delegates.  It does a great job with the real world boss/worker paralell that makes it really easy to follow.
http://www.codeproject.com/KB/cs/delegate_bedtime.aspx
0
 
LVL 1

Author Comment

by:nkewney
ID: 34112321
Thanks guys.

I'm going to study both solutions now and I'll let you know how I get on.
0
 
LVL 1

Author Comment

by:nkewney
ID: 34112434
Hi DaTribe,

I just wanted to confirm something with you.

Referring to your example below, am I correct in thinking that in this instance, the button click is in the "Lead Profile"

I'm trying to catch the event in the Navigator (just in case the user doesn't press save on the Profile page)

Is this correct?

Thanks again for your patience.

Nick
public class Navigator : System.Web.UI.UserControl
{
     public void Save()
     {
     }
}

// To make things really simple you could just
// reference the control directly from the page
// and call its save method
public class Profile: System.Web.UI.UserControl
{
    public void ButtonClick(object sender, EventArgs e)
    {
        ucNavigatorControl.Save();

        // Do something else
    }
}

Open in new window

0
 
LVL 18

Accepted Solution

by:
Richard Lee earned 500 total points
ID: 34154756
Apologies for the late response. I didn't realise you had come back to me - was busy off answering other questions.

Let me spell out again the scenario as I understand it and then respond to your question:

1. Profile user control
2. Navigator user control
3. Profile user control contains Navigator user control

--> Just as I was spelling this out I thought I would just code it and send it to you. Makes life easier for both of us.

See: http://www.avantprime.com/experts-exchange/avantprime.web.observer.zip

This is only a VS2008 project.

BTW: I have implemented a simple observer pattern.

DaTribe
0
 
LVL 1

Author Closing Comment

by:nkewney
ID: 34206010
Fantastic. Thank you so much.

Nick
0
 
LVL 18

Expert Comment

by:Richard Lee
ID: 34207226
Glad I could help.
0

Featured Post

Independent Software Vendors: 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

User art_snob (http://www.experts-exchange.com/M_6114203.html) encountered strange behavior of Android Web browser on his Mobile Web site. It took a while to find the true cause. It happens so, that the Android Web browser (at least up to OS ver. 2.…
Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
In this video, viewers will be given step by step instructions on adjusting mouse, pointer and cursor visibility in Microsoft Windows 10. The video seeks to educate those who are struggling with the new Windows 10 Graphical User Interface. Change Cu…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.

617 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