?
Solved

Nested Usercontrol events not firing

Posted on 2008-09-29
9
Medium Priority
?
2,979 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
[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
  • 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
Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

 

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 2000 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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

In my previous two articles we discussed Binary Serialization (http://www.experts-exchange.com/A_4362.html) and XML Serialization (http://www.experts-exchange.com/A_4425.html). In this article we will try to know more about SOAP (Simple Object Acces…
Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
Suggested Courses

765 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