Solved

Nested Usercontrol events not firing

Posted on 2008-09-29
9
2,946 Views
Last Modified: 2013-12-17
I have a couple of user controls.  One is a List, the other an item.  The List control is basically just a ListView that takes a few arguments and repeats the "Item" user control.  

The item user control is passed parameters form the list and has different functionality depending on those parameters.   This all works fine, my only issue is attaching a Click event to an imageButton is the "Item" control.

I think the issue has to do with the DataPager I have hooked up to the List control, in that for the datapager to work, I need to databind the List on postback.

Let me know if you need code samples, but I'm willing to change my code if someone can tell me how I should be doing this.


Thanks in Advance,
Justin
0
Comment
Question by:justy542
  • 4
  • 3
9 Comments
 
LVL 10

Expert Comment

by:jinn_hnnl
ID: 22603345
Well,

I think it doesn't really matter how deep your usercontrols are nested.

Do you define the event as the usercontrol is added (to the list, and this is not always the same). If you dynamically added these event, then make sure every time the page is load (the parent page), the event is defined again.

If your event is defined as one of the usercontrol property (happens in your aspx file). Then make sure your controls are render and parameters are passed on every PAGE POST BACK, I think they are.. but just to make sure.

If none of the case are true, may be we need some code for further assistance

JINN
0
 

Author Comment

by:justy542
ID: 22605443
I'm not sure how to add the event in time, as the event is added on itemDatabound.

Hopefully my code will help.

I'll post each file/codebehind in it's own post to keep confusion down.

first becaomeaFan.ascx (list)
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="becomeFan.ascx.cs" Inherits="controls_becomeFan" %>

<%@ Register Src="~/controls/athleteItem.ascx" TagPrefix="ic" TagName="athlete" %>
 

<asp:ListView ID="lvBecomeFan" runat="server" OnItemDataBound="lvBecomeFan_ItemDataBound">

    <LayoutTemplate>

        <div class="columnBlock">

	        <div class="sidebar_item_header ">

		        <div class="optionRight">

			        <a href="#">

				        no thanks 

			        </a>

		        </div>

		        <div class="intro">

			        <h2>

				        <span>

					        Become a Fan!</span><span class="sub">Choose the athletes/stars you're a fan of. 

				        </span>

			        </h2>

		        </div>

	        </div>

        <!-- item -->

        </div>

        <div class="columnBlockFrame">

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

        </div>
 

        <asp:DataPager ID="DataPager1" runat="server" PagedControlID="lvBecomeFan" PageSize="10" >

        <Fields>

        

            <skm:fbSafeNextPreviousPagerField 

                ShowFirstPageButton="true" 

                ShowLastPageButton="false" 

                ShowNextPageButton="false" 

                ShowPreviousPageButton="true" 

                FirstPageText="<<" 

                PreviousPageText="<" />

            <skm:fbSafeNumericPagerField ButtonCount="8" NextPageText="..." PreviousPageText="..."  />

            <skm:fbSafeNextPreviousPagerField  

                

                ShowFirstPageButton="false" 

                ShowLastPageButton="true" 

                ShowNextPageButton="true" 

                ShowPreviousPageButton="false" 

                 LastPageText=">>"

                 NextPageText=">"/>
 

  

        </Fields>

        </asp:DataPager>

    </LayoutTemplate>

    

    <ItemTemplate>

        <ic:athlete id="athleteItem" runat="server" />

    </ItemTemplate>

</asp:ListView>

Open in new window

0
 

Author Comment

by:justy542
ID: 22605450
becomeaFan.ascx.cs
using System;

using System.Collections;

using System.Configuration;

using System.Data;

using System.Linq;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.HtmlControls;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Xml.Linq;

using StarBurbs.Data;
 

public partial class controls_becomeFan : System.Web.UI.UserControl, System.Web.UI.INamingContainer

{

    protected void Page_PreRender(object sender, EventArgs e)

    {

    

            BindAthletes();

        

       

    }

    

    protected void BindAthletes()

    {

        lvBecomeFan.DataSource = Fetch.Athletes();

        lvBecomeFan.ItemPlaceholderID = "itemContainer";

        lvBecomeFan.DataBind();

    }

    protected void lvBecomeFan_ItemDataBound(object sender, ListViewItemEventArgs e)

    {

        if (e.Item.ItemType == ListViewItemType.DataItem)

        {

            ListViewDataItem lvDataItem = (ListViewDataItem)e.Item;

            Athlete a = lvDataItem.DataItem as Athlete;

            

            controls_athleteItem item = e.Item.FindControl("athleteItem") as controls_athleteItem;

            item.athlete = a;

            item.isSelectable = true;

            //ImageButton ib = item.FindControl("imgAthlete") as ImageButton;

            //ib.CommandArgument = a.id.ToString();

            //ib.Click += new ImageClickEventHandler(becomeFan);

        }

    }

    public void becomeFan(object sender, ImageClickEventArgs e)

    {

        ImageButton lb = sender as ImageButton;
 

        Label lbl = lb.FindControl("lblFan") as Label;

        lbl.Text = "You're A Fan!";

        StarBurbs.Data.Fetch.becomeFanOf(int.Parse(lb.CommandArgument));

    }

}

Open in new window

0
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 

Author Comment

by:justy542
ID: 22605452
athleteItem.ascx(item)
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="athleteItem.ascx.cs" Inherits="controls_athleteItem" %>
 

<div runat="server" id="athleteContainer" class="userBlock1">

    <asp:ImageButton ID="imgAthlete" runat="server" CssClass="athleteImage" />

	<p>

        <asp:Label ID="lblName" runat="server" Text="Label"></asp:Label>

	</p>

	<p class="action">

		<asp:Label ID="lblFan" runat="server" Text="Label"></asp:Label>

	</p>

</div>

Open in new window

0
 

Author Comment

by:justy542
ID: 22605459
athleteitem.ascx.cs
Hopefully this helps.  Thanks!!!
using System;

using System.Collections;

using System.Configuration;

using System.Data;

using System.Linq;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.HtmlControls;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Xml.Linq;

using ic.Facebook;
 

public partial class controls_athleteItem : System.Web.UI.UserControl, System.Web.UI.INamingContainer

{

    public Athlete athlete { get; set; }

    public bool isSelectable { get; set; }
 

    protected void Page_PreRender(object sender, EventArgs e)

    {
 

        imgAthlete.ImageUrl = athlete.imageUrl;

        imgAthlete.CommandArgument = athlete.id.ToString();
 

        lblName.Text = athlete.name;

        if (athlete.isFan)

        {

            lblFan.Text = "You're Already A Fan!";

        }

        else

        {

            lblFan.Text = "Become A Fan!";

        }
 

        //make div click do same as imgButton click, tricky ;)

        
 

        if (!isSelectable)

        {

            lblFan.Visible = false;

            athleteContainer.Attributes.Add("style", "cursor:pointer; cursor:hand;");

            athleteContainer.Attributes.Add("onclick", "document.setLocation('" + FButilities.makeFaceBookAppLink("~/athleteProfile.aspx?id=" + athlete.id.ToString() + "');"));

        

        }

        else {

            

            if (athlete.isFan)

            {

                athleteContainer.Attributes.Add("style", "cursor:pointer; cursor:hand;");

                athleteContainer.Attributes.Add("onclick", "document.setLocation('" + FButilities.makeFaceBookAppLink("~/athleteProfile.aspx?id=" + athlete.id.ToString() + "');"));

        

            }

            else

            {
 

                imgAthlete.Click += new ImageClickEventHandler(becomeFan);

            }

        }

    }
 
 

    protected override void CreateChildControls()

    {
 

        base.CreateChildControls();

    }

    public void becomeFan(object sender, ImageClickEventArgs e)

    {

        ImageButton lb = sender as ImageButton;

        

        lblFan.Text = "You're A Fan!";

        StarBurbs.Data.Fetch.becomeFanOf(int.Parse(lb.CommandArgument));

        athlete.isFan = true;

    }

    protected void visitProfile(object sender, ImageClickEventArgs e)

    {

        ImageButton lb = sender as ImageButton;

        HttpContext.Current.Response.Redirect(FButilities.makeFaceBookAppLink("~/athleteprofile.aspx?id=" + lb.CommandArgument));

    }

}

Open in new window

0
 
LVL 10

Accepted Solution

by:
jinn_hnnl earned 500 total points
ID: 22612307
Hi,

So I guess you have a list of athletes and if user clicks on the image he/she becomes a fan of that athletes. And this user should have logged in so in that Data.Fetch.BecomeFanOf would know about whose the action belongs to. Different case that image button will act differently regard to the fan status.

I have noticed, you dont have to do as you did. The javascript client click (as you add to button attribute and exist together with server button click). So you can leave the default behaviour of that IMAGEBUTTON click as becomeFan

If other case happen, you just have to return false in your client click which you added before. Well, this might not be the problem, but to make sure one thing works at a time.

You better make the:
 StarBurbs.Data.Fetch.becomeFanOf(...); in your item control

Then I see you want to set text for a Label outside of the athleteitem control scope. This is your problem... Your idea is right, but you might wanna use DELEGATE on this case (I have used similarly)

Look at my code

Notes: the delegate will be seen (so no worry), and using delegate is a very advance way to handle thing rendered outside of its own scope. The way I see your code, I think you have no problem understand how it works (because you have done something quite closed)

Hope this help



in your athleteitem control :
 

public delegate void OnBecomeAFanButtonClick()
 

public partial class controls_athleteItem : System.Web.UI.UserControl, ......

{

        public event OnBecomeAFanButtonClick evt_OnBecome fan;

.......
 
 
 

And in your list control becaomeaFan.ascx.cs, when you bind the item control
 

controls_athleteItem item = e.Item.FindControl("athleteItem") as controls_athleteItem;

item.athlete = a;

 item.isSelectable = true;

item.evt_OnBecome fan += OnBecomeAFanButtonClick(TheMethodYouUseToSetText);

Open in new window

0
 
LVL 10

Expert Comment

by:jinn_hnnl
ID: 22628616
Ok,

I have just come across the same problem and I remember about this still-open question.

Add to my previous post but more serious problem. Here is the problem, When you add any control dynamically, everytime the page is posted back, no matter what you do, you sou still have to add them again. That what you have done, but if there is any Click event within that control, the event will not be registered, and if you click on that button again. It might fired.

If you view the source of the page before and after the 1st post back you will find the CLIENT ID of the button is different. This is why you will never see server raise the button Click after the first post-back

It's a known problem. Make sure you register that click event.

Hope this helps
0

Featured Post

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

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

A quick way to get a menu to work on our website, is using the Menu control and assign it to a web.sitemap using SiteMapDataSource. Example of web.sitemap file: (CODE) Sample code to add to the page menu: (CODE) Running the application, we wi…
Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
This is used to tweak the memory usage for your computer, it is used for servers more so than workstations but just be careful editing registry settings as it may cause irreversible results. I hold no responsibility for anything you do to the regist…

867 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

15 Experts available now in Live!

Get 1:1 Help Now