Solved

Using abstract class to call a method of a page

Posted on 2011-03-23
20
376 Views
Last Modified: 2012-05-11
I have a page

Deals.aspx

in this page I have a usercontrol that is a grid. When items in this grid are updated I need to update the charts on the page (Deals.aspx).

The Deals.aspx page has subroutines that reload the charts

loadProducts() 'the chart

how do I, from the usercontrol, call Deals.loadProducts() ? I've made it a Public sub. I tried...

dim obj as new Deals
obj.loadProducts() ' but the chart is not recognized in the new Deals.aspx

It looks like it can be done with and abstract class and inheritance but I'm lost on how to put it together.

Thanks!
0
Comment
Question by:md0333
  • 8
  • 6
  • 2
  • +1
20 Comments
 
LVL 19

Expert Comment

by:Rikin Shah
ID: 35204424
Create a custom event on your user control using delegates and when update event is fired you can call function for updating charts.

http://www.devasp.net/net/articles/display/711.html
0
 

Author Comment

by:md0333
ID: 35204465
OK... still must be doing something wrong.

Put this in the Deals.aspx page

    Public Delegate Sub updateMyCharts()

    Public Sub updateAllCharts()
        loadProducts()
    End Sub


And trying to put this in my usercontrol it does not recognize UpdateMyCharts() without putting Deals. in front of it. then it doesn't see UpdateAllCharts() at all

        Dim obj As DealLog.updateMyCharts  'not seen without page in front
        obj = AddressOf updateallcharts()     'does not recognize sub
0
 

Author Comment

by:md0333
ID: 35210665
Any ideas what is wrong? Why the code I  tried is not working...

suggestions??
0
 

Author Comment

by:md0333
ID: 35223746
I changed the code in the usercontrol to;

        Dim obj As New DealLog.updateMyCharts(AddressOf DealLog.updateAllCharts)
        obj.updateAllCharts()

The first line tells me "Reference to a non-shared member requires and object reference"
Line 2 says "updateAllCharts is not a member of DealLog.updateMyCharts"
0
 

Author Comment

by:md0333
ID: 35224330
Here's the answer

I created a public sub in the .aspx page

Public Sub ucUpdateCharts()
    .... code here
End Sub

In my usercontrol I put this code where I need to call the page sub

Me.Page.GetType.InvokeMember("ucUpdateCharts", System.Reflection.BindingFlags.InvokeMethod, Nothing, Me.Page, New Object() {})
0
 
LVL 15

Expert Comment

by:Thogek
ID: 35224618
That GetType.InvokeMember approach should work, but the reflection API that it's using isn't very efficient compared to calling the method directly...

Have you tried something simpler like:

CType(Me.Page, Deals).ucUpdateCharts()

Open in new window

0
 

Author Comment

by:md0333
ID: 35224711
Worked also... and more efficient is better.

Thank you!
0
 

Author Comment

by:md0333
ID: 35224712
I would like to award the points to Thoqek...

Thank you.
0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 19

Expert Comment

by:daveamour
ID: 35224880
Your solution is horribly wrong!

Your user control is calling a method in the page.  Think of a simpler scenario where you have a button in a page.  You listen to the event click from your page and then run code in response.

The button should not need to know about the object containing it.

Delegates and events are the correct solution as suggested by other users.

http://www.audacs.co.uk/ViewPage.aspx?PageID=474
http://www.audacs.co.uk/ViewPage.aspx?PageID=476
0
 

Author Comment

by:md0333
ID: 35237913
I tried using delegates but I can't seem to get the syntax correct...

on my main page I have
    Public Delegate Sub myDel()

    Public Sub ucUpdateCharts()
        loadChart()
    End Sub

And in usercontrol I have tried a few different ways but none work

        Dim del As DealLog.myDel

        del = New DealLog.myDel(AddressOf ucUpdateCharts) 'ucUpdateCharts is not Declared

        del = AddressOf ucUpdateCharts 'ucUpdateCharts is not Declared


0
 
LVL 19

Expert Comment

by:daveamour
ID: 35238497
Ok this is a closed question so carry on with wht you have but I will code a solution for you, not fro points, just in the interests of good code.

Very busy at the moment though so I will do this at the weekend and then come and post it here.
0
 

Author Comment

by:md0333
ID: 35238569
I have no problem giving out another set of points... And I appreciate the help.
0
 
LVL 15

Expert Comment

by:Thogek
ID: 35245532
daveamour has a good point.  What I posted, and what you have, will work, but it creates an awareness by the control of its containing page that arguably violates some basic OO concepts, and would make re-using that control in another page more troublesome than it should be.

OTOH, simply having the control publish a public custom GridUpdated event to which the page can choose to subscribe and respond as it will, would decouple the dependency much more cleanly...
0
 
LVL 19

Expert Comment

by:daveamour
ID: 35250501
Yep Thoqek is spot on

This is what we should be striving for - clean, decoupled, cohesive code which is easy to maintain, reuse and extend!

0
 
LVL 19

Accepted Solution

by:
daveamour earned 500 total points
ID: 35303954
Ok this is all done.  I did it in C# and VB.net.

So we have a control and a page containing the control.  The control contains a button and when it is clicked the containing page will run code as it has subscribed to the event which I have added to the control.  Have a look and see if it makes sense.

The aspx is the same for C# and VB.net with just the code behind being different.


<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="VBServerControls._Default" %>

<%@ Register src="SomeControl.ascx" tagname="SomeControl" tagprefix="uc" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <uc:SomeControl ID="SomeControlInstance" runat="server" />

        <p>
            <asp:Literal ID="Message" runat="server" EnableViewState="false"></asp:Literal>
        </p>    
    </div>
    </form>
</body>
</html>

Open in new window

0
 
LVL 19

Assisted Solution

by:daveamour
daveamour earned 500 total points
ID: 35303962
Sorry I submitted that by mistake!

Here is the rest - you will have to change @ Page Language="vb" as required though!

I can send you the solution too if you like.
<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="SomeControl.ascx.vb" Inherits="VBServerControls.SomeControl" %>
<div style="border: 1px solid #000; padding: 20px; width: 400px; height: 80px; font-family: Verdana;">
    <p>
        This is my server control with a button <asp:Button ID="MyButton" 
            runat="server" Text="Click Me" onclick="MyButton_Click" />
    </p>
</div>

Public Class _Default
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    End Sub

    Protected Sub SomeControlInstance_ButtonClicked() Handles SomeControlInstance.ButtonClicked
        Message.Text = "The button was clicked (VB)"
    End Sub

End Class

Public Class SomeControl : Inherits System.Web.UI.UserControl
    Public Event ButtonClicked(ByVal sender As Object, ByVal e As EventArgs)

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    End Sub

    Protected Sub MyButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles MyButton.Click
        RaiseEvent ButtonClicked(sender, e)
    End Sub
End Class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace CSharpServerControls
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            SomeControlInstance.ButtonClicked += new EventHandler(SomeControlInstance_ButtonClicked);
        }

        protected void SomeControlInstance_ButtonClicked(object sender, EventArgs e)
        {
            Message.Text = "The button was clicked (C#)";
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace CSharpServerControls
{
    public partial class SomeControl : System.Web.UI.UserControl
    {
        public event EventHandler ButtonClicked;
        
        protected void Page_Load(object sender, EventArgs e)
        {
           
        }

        protected void MyButton_Click(object sender, EventArgs e)
        {
            if (ButtonClicked != null)
            {
                ButtonClicked.Invoke(sender, e);
            }
        }
    }
}

Open in new window

0
 
LVL 19

Expert Comment

by:daveamour
ID: 35308047
Thanks for the points :)
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Displaying an arrayList in a listView using the default adapter is rarely the best solution. To get full control of your display data, and to be able to refresh it after editing, requires the use of a custom adapter.
International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

744 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now