views:

155

answers:

1

I have a custom servercontrol that inherits from CompositeDataBoundControl. I have three templates: one header template, one footer template and one item template. The item template can contain a checkbox that I use to decide if I should delete the item.

In the footer and/or header templates I have a button with a CommandName of "DeleteItem". When that button is clicked, I handle the event in OnBubbleEvent:

if (cea.CommandName == "DeleteItem") {
    //loop through the item list and get the selected rows
    List<int> itemsToDelete = new List<int>();
    foreach(Control c in this.Controls){
        if (c is ItemData) {
            ItemData oid = (ItemData)c;
            CheckBox chkSel = (CheckBox)oid.FindControl("chkSelected");
            if (chkSel.Checked) {
                itemsToDelete.Add(oid.Item.Id);
            }
        }                        
    }
    foreach (int id in itemsToDelete) {
        DeleteItem(id);
    }
  }
}

The problem is that Item is null since the CreateChildControls method already has been run as asp.net needs to recreate the control hierarchy before the event fire. It uses the DummyDataSource and a list of null objects to recreate the control hierarchy:

IEnumerator e = dataSource.GetEnumerator();
if (e != null) {
while (e.MoveNext()) {
    ItemData container = new ItemData (e.Current as OrderItem);
    ITemplate itemTemplate = this.ItemTemplate;
    if (itemTemplate == null) {
        itemTemplate = new DefaultItemTemplate();
    }
    itemTemplate.InstantiateIn(container);
    Controls.Add(container);
    if (dataBinding) {
        container.DataBind();
    }
    counter++;
}

}

The problem is this line: ItemData container = new ItemData (e.Current as OrderItem); When the control hierarchy is rebuilt before the event is fired, the e.Current is null, so when I try to find out which item was marked for deletion, I get 0 since the original value has been overwritten.

Any suggestions on how to fix this?

A: 

I've finally found a solution that works. The problem is that the bound data is only connected to the control when being bound and directly after(normally accessed in a ItemDataBound event).

So to solve it I had to add a hidden literal containing the data item id to the container control. In the OnBubbleEvent I find the hidden literal and get the id:

ItemData oid = (ItemData)c;
CheckBox chkSel = (CheckBox)oid.FindControl("chkSelected");
if(chkSel != null) {
      if(chkSel.Checked) {
         Literal litId = (Literal)oid.FindControl("litId");
         itemsToDelete.Add(Utils.GetIntegerOnly(litId.Text));
      }
}
Vidar Langberget