CompositeDataBoundControl - 由于 DummyDataSource 在事件触发之前数据绑定值被覆盖

发布于 2024-08-20 04:10:35 字数 1571 浏览 2 评论 0原文

我有一个继承自 CompositeDataBoundControl 的自定义服务器控件。我有三个模板:一个页眉模板、一个页脚模板和一个项目模板。项目模板可以包含一个复选框,我用它来决定是否应该删除该项目。

在页脚和/或页眉模板中,我有一个 CommandName 为“DeleteItem”的按钮。单击该按钮时,我在 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);
    }
  }
}

问题是 Item 为 null,因为 CreateChildControls 方法已经运行,因为 asp.net 需要在事件触发之前重新创建控件层次结构。它使用 DummyDataSource 和一个空对象列表来重新创建控件层次结构:

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

}

问题是这一行: ItemData container = new ItemData (e.Current as OrderItem); 当之前重建控件层次结构时事件被触发,e.Current 为空,所以当我尝试找出哪个项目被标记为删除时,我得到 0,因为原始值已被覆盖。

关于如何解决这个问题有什么建议吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你与昨日 2024-08-27 04:10:35

我终于找到了一个有效的解决方案。问题在于,绑定数据仅在绑定时和绑定后立即连接到控件(通常在 ItemDataBound 事件中访问)。

因此,为了解决这个问题,我必须向容器控件添加一个包含数据项 id 的隐藏文字。在 OnBubbleEvent 中,我找到隐藏的文字并获取 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));
      }
}

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));
      }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文