ASP.NET:回发处理,没有触发事件 [英] ASP.NET: Postback processed without events being fired

查看:143
本文介绍了ASP.NET:回发处理,没有触发事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个GridView,动态创建的图像按钮,当点击时应该触发命令事件。事件处理基本上有效,除了第一次点击一个按钮。然后,回发处理,但事件没有被触发。



我已经尝试调试这个,在我看来,代码之前和之后执行的代码首次点击与其他任何点击完全相同。 (除了在第一次点击中,事件处理程序不被调用。)



有一些特殊之处:触发事件的按钮是通过数据绑定,即数据绑定必须在页面生命周期中执行两次:一旦加载,为了使按钮存在(否则,根本无法处理事件),并且一次渲染之前,以便在显示之后显示新数据事件已被处理。



我已阅读这些帖子,但不符合我的情况:
ASP.NET LinkBut​​ton OnClick事件在主页上不起作用
<一个href =http://stackoverflow.com/questions/96837/linkbutton-not-firing-on-production-server> LinkBut​​ton不在生产服务器上触发,
ASP.NET点击()事件不会在第二次回发上触发



详细信息:
GridView包含图像按钮在每一行。按钮的图像是数据绑定。这些行由GridView.DataBind()生成。为了实现这一点,我已经使用TemplateField与自定义ItemTemplate实现。 ItemTemplate的InstantiateIn方法创建ImageButton并为其分配相应的事件处理程序。此外,图像的DataBinding事件被分配一个处理程序,它根据相应行的数据检索适当的图像。



GridView放置在UserControl上。 UserControl定义GridView事件的事件处理程序。代码大致如下:

  private DataTable dataTable = new DataTable(); 
保护SPGridView网格;

protected override void OnLoad(EventArgs e)
{
DoDataBind(); //创建网格这对于回发事件的工作至关重要。
}

protected override void Render(HtmlTextWriter writer)
{
DoDataBind();
base.Render(writer); //根据最新的更改重新排列网格
}

void ReadButton_Command(object sender,CommandEventArgs e)
{
ImageButton button =(ImageButton)sender;
GridViewRow viewRow =(GridViewRow)button.NamingContainer;
int rowIndex = viewRow.RowIndex;

// rowIndex用于标识按钮被点击的行
//,因为所有行的control.ID相等。
// [...一些代码来处理事件...]
}

private void DoDataBind()
{
// [ ...一些代码来填充dataTable ...]

grid.AutoGenerateColumns = false;

grid.Columns.Clear();

TemplateField templateField = new TemplateField();
templateField.HeaderText =;
templateField.ItemTemplate = new MyItemTemplate(new CommandEventHandler(ReadButton_Command));
grid.Columns.Add(templateField);

grid.DataSource = this.dataTable.DefaultView;
grid.DataBind();
}

私有类MyItemTemplate:ITemplate
{
private CommandEventHandler commandEventHandler;

public MyItemTemplate(CommandEventHandler commandEventHandler)
{
this.commandEventHandler = commandEventHandler;
}

public void InstantiateIn(控制容器)
{
ImageButton imageButton = new ImageButton();
imageButton.ID =btnRead;
imageButton.Command + = commandEventHandler;
imageButton.DataBinding + = new EventHandler(imageButton_DataBinding);
container.Controls.Add(imageButton);
}

void imageButton_DataBinding(object sender,EventArgs e)
{
//代码获取图像URL
}
}

只需重复一遍:在每个生命周期中,首先执行OnLoad,并使用ImageButtons生成Grid。然后,处理事件。由于按钮在那里,事件通常工作。之后,调用Render,根据新数据从头开始生成Grid。除了第一次用户点击图像按钮以外,这一直是有效的,尽管我已经断言当网页首次发送给用户时也会生成网格和图像按钮。

$ b希望有人可以帮助我理解这一点,或者告诉我一个更好的解决方案。

解决方案

因为在我看来,这是一个部分答案,我以这种方式重新发布:




  • 如果我使用正常的按钮而不是ImageButtons(在完全相同的地方,即仍然使用MyItemTemplate,但在InstantiateIn中实例化Button而不是ImageButton,它的工作正常。


  • 如果我断言在发送内容到客户端之前,DoDataBind()总是执行两次,它可以用ImageButtons正常工作。




困惑,但无论如何...


I have a GridView with dynamically created image buttons that should fire command events when clicked. The event handling basically works, except for the very first time a button is clicked. Then, the postback is processed, but the event is not fired.

I have tried to debug this, and it seems to me, that the code executed before and after the first click is exactly the same as for any other clicks. (With the exception that in the first click, the event handler is not called.)

There is some peculiarity in that: The buttons which fire the event are created dynamically through databinding, i.e. databinding must be carried out twice in the page lifecycle: Once on load, in order to make the buttons exist (otherwise, events could not be handled at all), and once before rendering in order to display the new data after the events have been processed.

I have read these posts but they wouldn't match my situation: ASP.NET LinkButton OnClick Event Is Not Working On Home Page, LinkButton not firing on production server, ASP.NET Click() event doesn't fire on second postback

To the details: The GridView contains image buttons in each row. The images of the buttons are databound. The rows are generated by GridView.DataBind(). To achieve this, I have used the TemplateField with a custom ItemTemplate implementation. The ItemTemplate's InstantiateIn method creates the ImageButton and assigns it the according event handler. Further, the image's DataBinding event is assigned a handler that retrieves the appropriate image based on the respective row's data.

The GridView is placed on a UserControl. The UserControl defines the event handlers for the GridView's events. The code roughly looks as follows:

private DataTable dataTable = new DataTable();
protected SPGridView grid;

protected override void OnLoad(EventArgs e)
{
    DoDataBind(); // Creates the grid. This is essential in order for postback events to work.
}

protected override void Render(HtmlTextWriter writer)
{
    DoDataBind();
    base.Render(writer); // Renews the grid according to the latest changes
}

void ReadButton_Command(object sender, CommandEventArgs e)
{
    ImageButton button = (ImageButton)sender;
    GridViewRow viewRow = (GridViewRow)button.NamingContainer;
    int rowIndex = viewRow.RowIndex;

    // rowIndex is used to identify the row in which the button was clicked,
    // since the control.ID is equal for all rows.
    // [... some code to process the event ...]
}

private void DoDataBind()
{
    // [... Some code to fill the dataTable ...]

    grid.AutoGenerateColumns = false;

    grid.Columns.Clear();

    TemplateField templateField = new TemplateField();
    templateField.HeaderText = "";
    templateField.ItemTemplate = new MyItemTemplate(new CommandEventHandler(ReadButton_Command));
    grid.Columns.Add(templateField);

    grid.DataSource = this.dataTable.DefaultView;
    grid.DataBind();
}

private class MyItemTemplate : ITemplate
{
    private CommandEventHandler commandEventHandler;

    public MyItemTemplate(CommandEventHandler commandEventHandler)
    {
        this.commandEventHandler = commandEventHandler;
    }

    public void InstantiateIn(Control container)
    {
        ImageButton imageButton = new ImageButton();
        imageButton.ID = "btnRead";
        imageButton.Command += commandEventHandler;
        imageButton.DataBinding += new EventHandler(imageButton_DataBinding);
        container.Controls.Add(imageButton);
    }

    void imageButton_DataBinding(object sender, EventArgs e)
    {
        // Code to get image URL
    }
}

Just to repeat: At each lifecycle, first the OnLoad is executed, which generates the Grid with the ImageButtons. Then, the events are processed. Since the buttons are there, the events usually work. Afterwards, Render is called, which generates the Grid from scratch based upon the new data. This always works, except for the very first time the user clicks on an image button, although I have asserted that the grid and image buttons are also generated when the page is sent to the user for the first time.

Hope that someone can help me understand this or tell me a better solution for my situation.

解决方案

Since in my opinion this is a partial answer, I re-post it this way:

  • If I use normal Buttons instead of ImageButtons (in the exact same place, i.e. still using MyItemTemplate but instantiating Button instead of ImageButton in "InstantiateIn", it works fine.

  • If I assert that DoDataBind() is always executed twice before sending the content to the client, it works fine with ImageButtons.

Still puzzled, but whatever...

这篇关于ASP.NET:回发处理,没有触发事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆