클릭하면 명령 이벤트를 발생시켜야하는 동적으로 생성 된 이미지 버튼이있는 GridView가 있습니다. 이벤트 처리는 버튼을 처음 클릭하는 경우를 제외하고는 기본적으로 작동합니다. 그런 다음 다시 게시 처리되지만 이벤트가 발생하지 않습니다.ASP.NET : 이벤트가 실행되지 않고 포스트 백이 처리되었습니다.
이 코드를 디버깅하려고 시도한 결과, 첫 번째 클릭 전후에 실행 된 코드가 다른 모든 클릭과 완전히 동일하다고 생각됩니다. (첫 번째 클릭에서 이벤트 핸들러가 호출되지 않는다는 점을 제외하고는).
이벤트를 발생시키는 버튼은 데이터 바인딩을 통해 동적으로 생성됩니다. 즉, 데이터 바인딩은 데이터 바인딩을 통해 두 번 페이지 라이프 사이클 : 일단로드되면, 이벤트 처리 후 새 데이터를 표시하기 위해 버튼이 존재하도록 (그렇지 않으면 이벤트를 전혀 처리 할 수 없게) 렌더링하기 전에 한 번로드합니다.
나는이 글을 읽고 있지만 내 상황과 일치하지 않을 : 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
세부 사항에 :는 의 GridView 각 행에 이미지 버튼이 있습니다. 단추의 심상은 databound이다. 행은 GridView.DataBind()에 의해 생성됩니다. 이를 위해 CustomTemplate 구현과 함께 TemplateField를 사용했습니다. ItemTemplate의 InstantiateIn 메서드는 ImageButton을 만들고 해당 이벤트 처리기를 할당합니다. 또한 이미지의 DataBinding 이벤트에는 해당 행의 데이터를 기반으로 적절한 이미지를 검색하는 핸들러가 지정됩니다.
GridView는 UserControl에 배치됩니다. UserControl은 GridView의 이벤트에 대한 이벤트 처리기를 정의합니다.
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
}
}
그냥 반복 : 다음과 같이 코드는 대략 보이는 각각의 라이프 사이클에서 먼저의 OnLoad가 ImageButtons와 그리드를 생성하는 실행됩니다. 그런 다음 이벤트가 처리됩니다. 버튼이 있기 때문에 이벤트가 일반적으로 작동합니다. 그런 다음 Render가 호출되어 새로운 데이터를 기반으로 그리드를 처음부터 생성합니다. 페이지가 사용자에게 처음 전송 될 때 그리드 및 이미지 버튼이 생성된다는 것을 주장했지만 사용자가 이미지 버튼을 처음 클릭하는 경우를 제외하고는 항상 작동합니다.
누군가가 나를 이해하거나 내 상황에 대해 더 나은 해결책을 알려주기를 바랍니다.
안녕하세요. Bryan, 답장을 보내 주셔서 감사합니다. 내가 두 번 바인딩 이유는 위의 찾을 수 있습니다 : 첫 번째 시간 순서대로 이벤트가 해고 될 수 있도록 거기에되고; 이벤트 핸들러에 의해 변경된 사항에 따라 뷰를 갱신하기 위해 두 번째 시간. 포스트 백 후에 gridview를 databind하지 않으면 viewstate가 켜져 있어도 비어있는 것으로 판명됩니다. => ?? 따라서 모든 포스트 백 이후에 그리드를 데이터 바인딩해야합니다. – chiccodoro
CommandField의 문제점은 이미지를 데이터 바인딩 할 수 없다는 것입니다 (?). 모든 행에 대해 하나의 동일한 이미지를 정의해야합니다. 내 경우에는 대조적으로 이미지를 표시하려면 각 행의 데이터에 의존해야합니다. BoundField는 차례로 명령 이벤트를 제공하지 않습니다. 그래서 템플릿은 제가 발견 한 유일한 방법입니다. 내가 틀렸다면 나에게 정정 해주세요, 나는 이것이 사실일지도 모른다! – chiccodoro
두 HTML 파일 간의 차이점은 __REQUESTDIGEST, __EVENTVALIDATION, 그리고 물론 __VIEWSTATE에서 차이점을 나타 냈습니다. – chiccodoro