Link to home
Start Free TrialLog in
Avatar of steve_bagnall
steve_bagnall

asked on

ItemCommand event not propogating on ImageButton click

Sorry for the stingy point allocation, it's all I have left!  I have a datagrid with a dynamically generated template column below that contains an ImageButton.  I would like for when the button is clicked, the ItemCommand event is raised on the datagrid.  In the following code, this does not happen.  Is there a way to get this to work?  

Cheers, Steve.

public class DGTempColumn : System.Web.UI.Page
{
      protected System.Web.UI.WebControls.DataGrid DataGrid1;

      private void Page_Load(object sender, System.EventArgs e)
      {
            DataSet ds = new DataSet();
            DataTable dt = new DataTable();
            ds.Tables.Add(dt);
            dt.Columns.Add(new DataColumn("test 1"));
            dt.Columns.Add(new DataColumn("test 2"));

            DataRow dr = dt.NewRow();
            dr["test 1"] = "test 1 1";
            dr["test 2"] = "test 2 1";
            dt.Rows.Add(dr);

            dr = dt.NewRow();
            dr["test 1"] = "test 1 2";
            dr["test 2"] = "test 2 2";
            dt.Rows.Add(dr);

            DataGrid1.DataSource = ds;
            DataGrid1.DataBind();
      }

      private void Handle_DataGrid1ItemCommand(object sender, DataGridCommandEventArgs args)
      {
            string test = args.CommandName;      // NOT HIT
      }

      #region Web Form Designer generated code
      override protected void OnInit(EventArgs e)
      {
            TemplateColumn tmView = new TemplateColumn();
            tmView.HeaderTemplate = new AddColumn(ListItemType.Header, Page);
            tmView.ItemTemplate = new AddColumn(ListItemType.Item, Page);
            DataGrid1.Columns.Add(tmView);

            DataGrid1.ItemCommand += new DataGridCommandEventHandler(Handle_DataGrid1ItemCommand);
            InitializeComponent();
            base.OnInit(e);
      }

      /// <summary>
      /// Required method for Designer support - do not modify
      /// the contents of this method with the code editor.
      /// </summary>
      private void InitializeComponent()
      {    
            this.Load += new System.EventHandler(this.Page_Load);
      }
      #endregion
}

public class AddColumn : ITemplate
{
      private ListItemType templateType;
      private Page parentPage;

      public AddColumn(ListItemType type, Page page)
      {
            templateType = type;
            parentPage = page;
      }

      public void InstantiateIn(System.Web.UI.Control container)
      {
            switch(templateType)
            {
                  case ListItemType.Header:
                        break;
                            case ListItemType.Item:
                        ImageButton imgPlus = new ImageButton();
                        imgPlus.CommandName = "Add";
                        imgPlus.Width = 10;
                        imgPlus.ImageUrl = @"~/images/plus.gif";
                        imgPlus.ToolTip = "Click to add or insert.";
                        container.Controls.Add(imgPlus);
                        break;
            }
      }
}

Avatar of Bob Learned
Bob Learned
Flag of United States of America image

Did you try adding an event handler to button when it is defined?

Bob
Avatar of steve_bagnall
steve_bagnall

ASKER

And raise an event in the template column you mean?  If so do you know how I attach an event handler to the template?

Cheers, Steve
I was thinking that it would probably be easier in the DataGrid.ItemCreated or DataGrid.ItemDataBound event handlers.

Bob
The ImageButton control doesn't seem to exist yet when I try and attach an event handler to it on either of those events.  Any other ideas?

Steve
Steve,

Is this an ItemTemplate or EditItemTemplate?

Bob
ItemTemplate
What does the generated HTML <table> look like?

Bob
This is with the original code:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
      <HEAD>
            <title>DGTempColumn</title>
            <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
            <meta name="CODE_LANGUAGE" Content="C#">
            <meta name="vs_defaultClientScript" content="JavaScript">
            <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
      </HEAD>
      <body MS_POSITIONING="GridLayout">
            <form name="Form1" method="post" action="DGTempColumn.aspx" id="Form1">
<input type="hidden" name="__VIEWSTATE" value="<VIEWSTATE>" />

                  <table cellspacing="0" rules="all" border="1" id="DataGrid1" style="border-collapse:collapse;Z-INDEX: 101; LEFT: 232px; POSITION: absolute; TOP: 184px">
      <tr>
            <td></td><td>test 1</td><td>test 2</td>
      </tr><tr>
            <td><input type="image" name="DataGrid1:_ctl2:_ctl0" title="Click to add or insert the first divert." src="images/expandingdatagrid_plus.gif" alt="" border="0" style="width:10px;" /></td><td>test 1 1</td><td>test 2 1</td>
      </tr><tr>
            <td><input type="image" name="DataGrid1:_ctl3:_ctl0" title="Click to add or insert the first divert." src="images/expandingdatagrid_plus.gif" alt="" border="0" style="width:10px;" /></td><td>test 1 2</td><td>test 2 2</td>
      </tr>
</table>
            </form>
      </body>
</HTML>
I see the ImageButton here:
   <input type="image" name="DataGrid1:_ctl2:_ctl0"

The control doesn't seem to have an ID assigned, so that you could use FindControl("id") to get a reference to the ImageButton.

Bob
if im correct the ItemCommand event only fires for the Button control.. any1 else u have to manually add the handler (might be wrong)

so at the ItemCreated event of the DataGrid try like this

(ps. in VB.NET )

Private Sub DataGrid1_ItemCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataListItemEventArgs) Handles DataList1.ItemCreated
                    Dim chk As ImageButton = e.Item.FindControl("ImageButtonID")
                    AddHandler chk.Clicked, AddressOf Chk_Click
                End Sub

Private Sub Chk_Click(ByVal sender As Object, ByVal e As System.EventArgs)
  'here it will fire wenever the imagebutton is clicked
end sub


not tested but should work with minor changes
Giving the Image button an ID of "badger" produces the following

<input type="image" name="DataGrid1:_ctl2:badger" id="DataGrid1__ctl2_badger" title="Click to add or insert the first divert." src="images/expandingdatagrid_plus.gif" alt="" border="0" style="width:10px;" />

and,

<input type="image" name="DataGrid1:_ctl3:badger" id="DataGrid1__ctl3_badger" title="Click to add or insert the first divert." src="images/expandingdatagrid_plus.gif" alt="" border="0" style="width:10px;" />

Are you saying that I need to predict these IDs in some way?
u saying to me ?

if the imageid is badger then:

  Dim chk As ImageButton = e.Item.FindControl("badger")

.NET knows who's who (at least in the itemCreated)

eguilherme,

The image button doesn't seem to exist at create, chk in your code is null when I attempt to add the event handler to it having added an ID property to the image and using args.Item.FindControl("ID").

Steve
eguilherme, my comment before last was not to you, but my last one was
Yeah, the control won't exist until the grid is bound to the DataSource--use ItemDataBound event handler instead.

Bob
sorry guys - the button is undefined in DataBinding too
Any ideas, should that have worked?
are u sure the ImageButton Control Id is "ID" ?

args.Item.FindControl("ID")

well when i get home i ll try to make a workin example to show u..

btw.. are u using asp.net 1 or 2 ??

The ID is actually "badger", but I am also using args.Item.FindControl("badger") (I use args instead of e for some reason!)
Yeah I am using .NET 1.1
SOLUTION
Avatar of Edgard Yamashita
Edgard Yamashita
Flag of Brazil image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks eguilherme
If you put a breakpoint in ItemDataBound event handler, is it going into that?  Also, you can check the controls for each cell for the DataGridItem.

Bob
Bob,

I've tried putting a breakpoint in the event handler, that's how I know that the ImageButton object is null.  Also, the first method I used to try and access the ImageButton was to get the right cell in the e.Item.Cells collection, then access the Controls property (which was empty), before I used the FindControl method.  So I'm pretty sure that it's not working as planned.  I wouldn't have thought this would be so difficult, perhaps I'm missing something obvious!

Steve
Steve,

This should work as advertised.  I see this:

   <td><input type="image"

That means that you have an HTML table cell, and a control for the cell.

Bob
I know, but it doesn't seem to exist at the time of either DataBind or ItemCreate, are you saying that it should?
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
private void Handle_DataGrid1ItemDataBound(object sender, DataGridItemEventArgs args)
{
      ImageButton btn = (ImageButton)args.Item.FindControl("badger");
      btn.Command += new CommandEventHandler(Handle_btnCommand);
}
Sorry guys solved it (it is pretty simple too) - the DataBind for the DataGrid needs to go in a if(!IsPostBack), cause it resets everything - doh!  Thanks both for your help though - I'll share the points as there aren't many and I'm sure you helped me get there.