[Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2992
  • Last Modified:

Nested Usercontrol events not firing

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
justy542
Asked:
justy542
  • 4
  • 3
1 Solution
 
jinn_hnnlCommented:
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
 
justy542Author Commented:
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
 
justy542Author Commented:
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
Restore individual SQL databases with ease

Veeam Explorer for Microsoft SQL Server delivers an easy-to-use, wizard-driven interface for restoring your databases from a backup. No expert SQL background required. Web interface provides a complete view of all available SQL databases to simplify the recovery of lost database

 
justy542Author Commented:
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
 
justy542Author Commented:
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
 
jinn_hnnlCommented:
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
 
jinn_hnnlCommented:
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

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now