0

我在 ASP 及其生命周期中有一个反复出现的问题,即在 Page_Load 事件引发之前捕获事件。例如,这里我正在自定义一个 gridview,它继承自 gridView 类。我添加了一个下拉列表来选择要跳转的页面(PageIndexChanged)。一切都会很好,除了这个下拉列表的 SelectedIndexChanged 事件在我渲染它之后被调用(网格和我的下拉列表在每次回发时重新生成)。所以我无法在其中选择正确的值。

所以我的事件只在第二次回发时提出,我总是迟到一个回发。

该下拉列表被添加到 RowCreated 事件中。我在其他事件中尝试过,但它是否为时已晚或太早(如果太晚则不渲染,如果太早则缺少元素)。

有什么解决办法吗?

PS:我发现这篇文章可以帮助我,但我不知道该怎么做:

进行控制或继承/扩展时要考虑的要点:

  1. 您必须通过覆盖调用 base.CreateChildControls() 的 CreateChildControls 来创建要引发事件的任何项目,然后执行您想要的任何操作(即在您的情况下添加行)。
  2. 列表项 DataBinding 您呈现的方式非常...非 kosher....您应该通过覆盖 DataBind() 来简化它,以便它清除子项,然后调用 EnsureChildControls(),然后添加新行...这样它很好的 ViewStated、持久化和事件管理。简单得多。
  3. 再次列出项目:也不要太早创建子控件:避免直接在 OnInit 或 onLoad 中创建子控件。这是一个错误。最好是让系统在需要时调用 EnsureChildControls(它会在第一页加载时在 PreRender 中,在 PostBack 中,如果它有子事件,则在 OnInit 之后调用它)......更糟糕的是,让 OnInit、OnLoad调用 EnsureChildControls()。
4

2 回答 2

1

您所关注的 msdn 页面是ASP.NET Page Life Cycle Overview,它有一个有用的表格,告诉您在页面的整个生命周期中发生的所有事件。

您可能需要以下之一(来自上面的链接):

预初始化

在启动阶段完成后和初始化阶段开始之前引发。

将此事件用于以下情况:

  • 检查 IsPostBack 属性以确定这是否是第一次处理页面。此时还设置了 IsCallback 和 IsCrossPagePostBack 属性。
  • 创建或重新创建动态控件。
  • 动态设置母版页。
  • 动态设置 Theme 属性。
  • 读取或设置配置文件属性值。

在里面

在初始化所有控件并应用任何皮肤设置后引发。单个控件的 Init 事件发生在页面的 Init 事件之前。

使用此事件来读取或初始化控件属性。

初始化完成

在页面初始化阶段结束时引发。在 Init 和 InitComplete 事件之间只发生了一项操作:打开了对视图状态更改的跟踪。视图状态跟踪使控件能够保留以编程方式添加到 ViewState 集合的任何值。在打开视图状态跟踪之前,添加到视图状态的任何值都会在回发过程中丢失。控件通常在引发其 Init 事件后立即打开视图状态跟踪。

使用此事件更改您希望确保在下一次回发后保持不变的视图状态。

预载

在页面加载其自身和所有控件的视图状态之后以及在它处理包含在 Request 实例中的回发数据之后引发。

于 2013-03-07T09:42:11.510 回答
0

好的,由于我上面给出的文章和这篇文章以及大量搜索,我终于解决了我的问题:

public class MyGridView : GridView
{
    TextBox txtSearch;

    protected override int CreateChildControls(System.Collections.IEnumerable dataSource, bool dataBinding)
    {
        int numRows = base.CreateChildControls(dataSource, dataBinding);

        // Create a new row
        GridViewRow rowSearch = base.CreateRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal);

        //convert the existing columns into an array, initialize and then add the row to the previously created table
        DataControlField[] fields = new DataControlField[this.Columns.Count];
        this.Columns.CopyTo(fields, 0);
        this.InitializeRow(rowSearch, fields);

        TableCell cellSearch = new TableCell();
        rowSearch.Cells.Add(cellSearch);

        txtSearch = new TextBox();
        txtSearch.Text = this.SearchTextboxDefaultValue;
        txtSearch.ID = "txtSearch";
        txtSearch.AutoPostBack = true;
        txtSearch.TextChanged += new EventHandler(txtSearch_TextChanged);
        cellSearch.Controls.Add(txtSearch);

        this.Controls[0].Controls.Add(rowSearch); // Controls[0] is a Table element

        return numRows;
    }

    protected void txtSearch_TextChanged(object sender, EventArgs e)
    {
        string search = (sender as TextBox).Text;
        DataTable dt = new DataTable();

        // We fill in dt with results, and rebind it

        this.DataSource = dt;
        this.DataBind();
    }
}

在 Page.cs 中:

private DataTable dt;

protected void Page_Load(object sender, EventArgs e)
{
    sampleDataTable();
    if (!Page.IsPostBack)
    {
        myGrid.DataSource = dt;
        myGrid.DataBind();
    }
}

private void sampleDataTable()
{
    // Populate the dataTable
}

谢谢

于 2013-03-08T15:21:23.743 回答