【问题标题】:ListControl.DataBind() doesn't work as expectedListControl.DataBind() 不能按预期工作
【发布时间】:2011-05-20 09:21:54
【问题描述】:

我遇到了问题。我有一个动态创建控件的 ASP.NET 项目。甚至更多的控件依赖于另一个控件(在回发时),因此它们可以改变它们的外观。

我有 ListControl 并以一种方法将其与数据绑定:

public static class ListControlExtensions
{
    public static void BindList(this ListControl list, IEnumerable dataSource, string valueKey, string textKey)
    {
        list.Items.Clear();
        list.Items.Add(new ListItem("(Empty)", "-1"));

        list.AppendDataBoundItems = true;
        list.DataSource = dataSource;
        list.DataValueField = valueKey;
        list.DataTextField = textKey;
        list.DataBind();
    }
}

传入的 dataSource 是好的(正如预期的,由于业务逻辑),但呈现的列表控件自上次 BindList 以来没有改变。所以问题 - 第一个数据绑定后的列表控件(使用默认数据源)在以后的数据绑定后不会改变。

BindList 在 OnInit 处调用:

protected override void OnInit(EventArgs e)
{
    base.OnInit(e);

    if (CompaniesList != null)
    {
        BindCompaniesList(CompaniesList, valueToFilter);
    }
}

protected void BindCompaniesList(ListControl listToBind, String valueToFilter)
{
    if (listToBind != null)
    {
        var list = Helper.GetCompanies();
        foreach (var item in list.Where(item => item.Value == valueToFilter))
        {
            item.Value = "-1";
        }
        listToBind.BindList(list, "Value", "Text");        
     }
}

FIXED: 解决方案:我认为问题是 LoadViewState 发生在 OnInit 之后,它用以前的数据覆盖 ListControl,存储在 ViewState 中。因此,我将 DataBind 从 OnInit 移至 OnLoad,并缓存了选定的值,因为绑定会重置它。

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);

    if (CompaniesList != null)
    {
        var selected = CompaniesList.SelectedIndex;
        BindCompaniesList(CompaniesList, valueToFilter);
        CompaniesList.SelectedIndex = selected;
    }
}

【问题讨论】:

  • 您的意思是您的列表仅在第一次被绑定而不是在回发时?
  • 我每次在加载控件时都绑定 - 但我认为问题是 LoadViewState 发生在 OnInit 之后,它用以前的数据覆盖 ListControl,存储在 ViewState 中。所以我把绑定移到了 OnLoad

标签: c# asp.net


【解决方案1】:

我建议将绑定代码移至 OnLoad,根据您的代码的工作方式,它应该看起来像这样

if (!Page.IsPostBack())
{
      if (CompaniesList != null)      
      {          BindCompaniesList(CompaniesList, valueToFilter);      }
}

我建议在绑定代码中尝试一下

public static void BindList(this ListControl list, IEnumerable dataSource, string valueKey, string textKey)        
{
        list.DataSource = dataSource;
        list.DataValueField = valueKey;
        list.DataTextField = textKey;
        list.DataBind();
        list.Insert(0, new ListItem("(Empty)", "-1"));    
    }

【讨论】:

  • 我无法将绑定放入!IsPostBack,因为我必须在 PostBack 中绑定数据列表。
【解决方案2】:

我认为您在 PostBack 上绑定列表,其中数据源没有任何价值,因此请确保在您调用该方法时数据源具有某些价值。

【讨论】:

  • 数据源充满了正确的项目,正如我所说的。我认为,问题出在 ListControl 的 ViewState 上。在@Andrew 建议之后,我已经将绑定移到了 Load-event 中——它现在正确地填充了 listcontrol,但没有保存选定的值。所以我提出了解决方案,并在我的帖子中更新。
【解决方案3】:

你可以试试PreRender页面事件。
ASP.NET Page Life Cycle Overview

在 Page 对象之后引发 创建了所有需要的控件 为了呈现页面,包括 复合控件的子控件。

【讨论】: