• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 305
  • Last Modified:

C# Trouble with simple event handling within an EditItemTemplate

I have a form that has a bog standard 'Add' news details input form. Below this a DataList so the user can view and update their details via the EditItemTemplate. So basically 2 seperate areas/code etc on 1 page.

Both these areas have calendar controls that are made visible only when the user clicks a calendar icon. Once the calendar is visible the user can use the OnSelectionChanged event handler to update the date text field for the news table.

I realise this is bog standard stuff and the simple 'Add' form works like a dream. I guess this is because the ImageButton (calendar icon) and calendar control is already sitting there on the page. However, a similar setup in the EditItemTemplate is giving me grief as I am getting the error of:

"Object reference not set to an instance of an object"

for

"
Line 438:            public void ibDateEditIcon_Click(object sender, System.Web.UI.ImageClickEventArgs e)
Line 439:            {
Line 440:                  this.calEditNewsDateSelect.Visible=true;
Line 441:            }
 "

The calendar control (which is working) is initialised as you'd expect:

private void InitializeComponent()
{  
      this.ibDateIcon.Click += new System.Web.UI.ImageClickEventHandler(this.ibDateIcon_Click);
      this.calNewsDateSelect.SelectionChanged += new System.EventHandler
                       (this.calNewsDateSelect_SelectionChanged);
}

BUT if I add the control that appear in the EditItemTemplate into this like this:

private void InitializeComponent()
{  
      this.ibDateIcon.Click += new System.Web.UI.ImageClickEventHandler(this.ibDateIcon_Click);
      this.calNewsDateSelect.SelectionChanged += new System.EventHandler
                       (this.calNewsDateSelect_SelectionChanged);
      this.ibDateEditIcon.Click += new System.Web.UI.ImageClickEventHandler(this.ibDateEditIcon_Click);
      this.calNewsEditDateSelect.SelectionChanged += new System.EventHandler
                       (this.calNewsEditDateSelect_SelectionChanged);
}

I get an instant error of:

"Object reference not set to an instance of an object. "

Line 421:            this.ibDateEditIcon.Click += new System.Web.UI.ImageClickEventHandler(this.ibDateEditIcon_Click);

I guess this is because I'm trying to initialise a control that only appears in the EditItemTemplate and therefore does not exist yet.

So, what do I do to get around this. I would have thought it'd be quite simple but I'm stumped (and it's important for us to keep our client happy).

Many thanks in advance.

Chris.
0
w3digital
Asked:
w3digital
  • 4
  • 2
1 Solution
 
b1xml2Commented:
The eThe errors you face can be explained as follows:

1. Anything in the Template Columns of Repeaters, Data Lists and Data Grids do not exist until they are created. They are created when data is bound to these objects.
2. When data is bound to these controls, the ItemCreated event gets fired. This creates the appropriate controls within the templated columns.
3. Then the ItemDataBound event gets fired, where the controls created are populated with the data.
4. When the controls are populated and a postback occurs, the controls get reconstructed during the Init Event and the ViewState is re-constructed and just after the Init event ends and before the Load event begins.
5. More important, these controls implement the INamingContainer interface, meaning that ANY controls created within it is not available directly via the page, thus the keyword this.<control_inside_template> does not occur.


0
 
b1xml2Commented:
6. The EditItemTemplate is only ever used when the EditItemIndex is greater than -1. So on top of the fact that the controls are only created after you set the data source and call the databound method,
there is no guarantee that the controls in the edit item template exists unless the EditItemIndex is set to greater than -1 (in short targeting any existing Item in the DataList)

1st solution
=========
hook up to the ItemCreatedEvent
private void InitializeComponent()
{  
     this.ibDateIcon.Click += new System.Web.UI.ImageClickEventHandler(this.ibDateIcon_Click);
     this.calNewsDateSelect.SelectionChanged += new System.EventHandler
                       (this.calNewsDateSelect_SelectionChanged);
     this.ibDateEditIcon.Click += new System.Web.UI.ImageClickEventHandler(this.ibDateEditIcon_Click);
     this.calNewsEditDateSelect.SelectionChanged += new System.EventHandler
                       (this.calNewsEditDateSelect_SelectionChanged);
}



private void MyDataList_ItemCreated(object sender,DataListItemEventArgs e)
{
      switch (e.Item.ItemType)
      {
            case ListItemType.Edit:
                  ImageButton imageButton = e.Item.FindControl("ibDateEditIcon") as ImageButton;
                  if (imageButton != null)
                  {
                        imageButton.Click += new ImageClickEventHandler(this.ibDateEditIcon_Click);
                  }
                  break;
      }
}

2nd solution
==========
<EditItemTemplate>
<asp:ImageButton Id="ibDateEditIcon" runat="server" onclick="ibDateEditIcon_Click" />
</EditItemTemplate>


code behind
==========
//make sure the access is either public or protected
public void ibDateEditIcon_Click(object sender, System.Web.UI.ImageClickEventArgs e)
{
      this.calEditNewsDateSelect.Visible=true;
}
0
 
w3digitalAuthor Commented:
Fantastic answer. I certainly feel a little more educated now.

Just about to try solution 1.

Incidentally solution 2 is what I was trying to use when I discovered the problem. This works for my first calendar object on the page (the one in the bog standard form) but not for the calendar object within the EditItemTemplate.

I've compared the two many times to see if I have any inconsistentices in the code that may cause one to work but not the other and they are basically identical (with different names and event of course). Any obvious thing I may be missing. I just assumed it couldn't be done that way (because of the suprise error).

I'll post the results of my implementation of your solution 1 in a mo. I have every faith in it working of course.

All the best,

Chris.
0
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

 
b1xml2Commented:
just addendum (i knew I forgot to write down something!!)
==========
1. Hook up the DataLists ItemCreated event
private void InitializeComponent()
{  
     this.ibDateIcon.Click += new System.Web.UI.ImageClickEventHandler(this.ibDateIcon_Click);
     this.calNewsDateSelect.SelectionChanged += new System.EventHandler
                       (this.calNewsDateSelect_SelectionChanged);
     this.DataList1.ItemCreated += new DataListItemEventHander(this.MyDataList_ItemCreated);
     this.calNewsEditDateSelect.SelectionChanged += new System.EventHandler
                       (this.calNewsEditDateSelect_SelectionChanged);
}
0
 
w3digitalAuthor Commented:
I think the problem is more fundamental somehow.

Despite implementing the above code (which I'm sure is correct so I will award you the points) , that being your solution 1.

AND

Trying your simpler solution 2 (which uses the approach I trying to begin with) I'm getting the exact same error on all occassions.

That error being on line 457:

"Object reference not set to an instance of an object

public void ibDateEditIcon_Click(object sender, System.Web.UI.ImageClickEventArgs e)
Line 456:            {
Line 457:                  this.calNewsEditDateSelect.Visible=true;
Line 458:            }

This brings me back to the start, so the script is basically telling me I haven't instantiated the "calNewsEditDateSelect" object!!????!! BUT I try to reference it whilst in EditItemTemplate mode so actually it IS instantiated surely?

So here is solution 1 in breif. I must be missing something glaringly obvious:

===================================
news.aspx
===================================
<EditItemTemplate>

    <asp:ImageButton id="ibDateEditIcon" runat="server" ImageUrl="/images/calendar.gif" CausesValidation="False"></asp:ImageButton>

    <asp:Calendar Visible="False" id="calNewsEditDateSelect" runat="server" OnSelectionChanged="calNewsEditDateSelect_SelectionChanged"></asp:Calendar>

</EditItemTemplate>

===================================
news.aspx.cs
===================================
using etc.....
namespace admin
{
    public class news : BasePage
    {
        protected System.Web.UI.WebControls.Calendar calNewsEditDateSelect;
        protected System.Web.UI.WebControls.ImageButton ibDateEditIcon;
   
        private void InitializeComponent()
        {  
            this.ibDateIcon.Click += new System.Web.UI.ImageClickEventHandler(this.ibDateIcon_Click);
            this.calNewsDateSelect.SelectionChanged += new System.EventHandler
                       (this.calNewsDateSelect_SelectionChanged);
            this.DataList1.ItemCreated += new DataListItemEventHander(this.MyDataList_ItemCreated);
            this.calNewsEditDateSelect.SelectionChanged += new System.EventHandler
                       (this.calNewsEditDateSelect_SelectionChanged);

            this.DataListNews.ItemCreated += new DataListItemEventHandler(this.data_ItemCreated);
        }

        private void data_ItemCreated(object sender, DataListItemEventArgs e)
        {
      ImageButton ib = (ImageButton)e.Item.FindControl("ImgBtDelete");
      if (ib != null)
          ib.Attributes.Add("OnClick", "if (confirm('Delete this Article?')){return true;}else{return false;}");
                  
      ImageButton ibEditCal = (ImageButton)e.Item.FindControl("ibDateEditIcon");
      if (ibEditCal != null)
          {
          ibEditCal.Click += new ImageClickEventHandler(this.ibDateEditIcon_Click);
          }                  
        }

// NOTE: You'll notice this does not have the switch statement you suggested: "case ListItemType.Edit:". I got the build error : "(401): 'System.Web.UI.WebControls.ListItemType' does not contain a definition for 'Edit'"

        public void ibDateEditIcon_Click(object sender, System.Web.UI.ImageClickEventArgs e)
        {
            this.calNewsEditDateSelect.Visible=true;
        }
    }
}

See anything wrong? Should I just shoot myself and put myself out of my misery?

Many thanks.

Chris
0
 
b1xml2Commented:

// NOTE: You'll notice this does not have the switch statement you suggested: "case ListItemType.Edit:". I got the build error : "(401): 'System.Web.UI.WebControls.ListItemType' does not contain a definition for 'Edit'"

change that to ListItemType.EditItem
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

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