简体   繁体   中英

CompositeDataBoundControl - databound values overwritten before event is fired due to DummyDataSource

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?

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));
      }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM