【问题标题】:Dynamically created buttons don't fire routine动态创建的按钮不会触发例程
【发布时间】:2015-08-03 01:37:20
【问题描述】:

我有一个带有模板列的gridview:

<asp:UpdatePanel runat="server">  
 <ContentTemplate>  
  <asp:GridView ID="gridDay" runat="server" SkinID="gridviewSkinLight" AutoGenerateColumns="False" DataSourceID="DSAppointmentForDay">  
   <Columns>  
    <asp:BoundField DataField="TimeValue" HeaderText="" InsertVisible="False" ReadOnly="True" SortExpression="TimeValue" />  
    <asp:TemplateField HeaderText=" ">  
     <ItemStyle HorizontalAlign="Left" />  
    </asp:TemplateField>  
   </Columns>  
  </asp:GridView>  
 </ContentTemplate>  
 <Triggers>  
  <asp:AsyncPostBackTrigger ControlID="gridDay" />  
 </Triggers>  
</asp:UpdatePanel>  

在 RowDataBound 上,如果找到符合条件的数据,我会在单元格中创建按钮:

Dim cmdNew As New Button  
cmdNew.ID = "E" & dr("pkAppointment") & "|" & dr("ApptTopic")  
AddHandler cmdNew.Click, AddressOf mySub  
cmdNew.Text = dr("ApptTopic") & " >> " & dr("ApptLocation")  
cmdNew.ToolTip = "Topic: " & dr("ApptTopic") & vbLf &
                 "Location: " & dr("ApptLocation")  
e.Row.Cells(1).Controls.Add(cmdNew)  

到这里为止,一切都很好。这些按钮是在右侧单元格中创建的,带有所有的花里胡哨。

按钮应该调用的例程是:

Private Sub mySub(sender As System.Object, e As System.EventArgs)
    Try
        Dim btn As Button = DirectCast(sender, Button)
        MsgBox(btn.Text)

    Catch ex As Exception

    End Try
End Sub  

点击按钮的那一刻,页面刷新,所有创建的按钮都消失了,mySub 也没有被调用。

我错过了什么吗?

【问题讨论】:

    标签: vb.net button gridview dynamic addressof


    【解决方案1】:

    试试这个,

    1) 添加一个脚本管理器,

    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    

    2)在gridview的OnRowCreated事件上创建按钮,将按钮注册为控件。

    Dim cmdNew As New Button  
    cmdNew.ID = "E" & dr("pkAppointment") & "|" & dr("ApptTopic")  
    cmdNew.Text = dr("ApptTopic") & " >> " & dr("ApptLocation")  
    cmdNew.ToolTip = "Topic: " & dr("ApptTopic") & vbLf &
                     "Location: " & dr("ApptLocation") 
    
    ScriptManager1.RegisterAsyncPostBackControl(cmdNew) 
    e.Row.Cells(1).Controls.Add(cmdNew)  
    
    AddHandler cmdNew.Click, AddressOf mySub  
    ScriptManager.GetCurrent(Me).RegisterAsyncPostBackControl(cmdNew)
    

    更新(已测试)

    1) 由于母版页中已有 ScriptManager,因此不需要新的。

    2) 使用UpdatePanel,像这样

    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" OnRowDataBound="CreateButtons" >
                <Columns>
                    <asp:BoundField DataField="Code" /> <!-- example column -->
                    <asp:BoundField DataField="Text" /> <!-- example column -->
                    <asp:CommandField />
                </Columns>
            </asp:GridView>
        </ContentTemplate>
        <Triggers>
            <asp:AsyncPostBackTrigger ControlID="GridView1"/>
        </Triggers>
    </asp:UpdatePanel>
    

    3) 在您的代码隐藏中,在OnRowDataBound 中创建按钮并在ScriptManager 中注册按钮,类似这样

    Protected Sub CreateButtons(ByVal sender As Object, ByVal e As GridViewRowEventArgs)
    
        If e.Row.RowType = DataControlRowType.DataRow Then
            Dim cmdNew As New Button
            cmdNew.ID = "Button" & e.Row.RowIndex
            cmdNew.Text = "Button" & e.Row.RowIndex
            cmdNew.ToolTip = "Button" & e.Row.RowIndex
    
            AddHandler cmdNew.Click, AddressOf CmdNewOnClick
    
            e.Row.Cells(2).Controls.Add(cmdNew)
            Dim myScriptManager As ScriptManager = Page.Master.FindControl("ScriptManager1")
            myScriptManager.RegisterAsyncPostBackControl(cmdNew)
    
        End If
    
    End Sub
    
    Private Sub CmdNewOnClick(ByVal sender As Object, ByVal e As EventArgs)
        Dim buttonClicked As Button = sender
        Debug.WriteLine("-----------------------------------------------")
        Debug.WriteLine("Button clicked:" & buttonClicked.ID)
        Debug.WriteLine("-----------------------------------------------")
    End Sub
    

    一个演示项目可用here

    【讨论】:

    • 我使用包含 ScriptManager 的 Site.Master。我将您的代码替换为Dim myScriptManager As ScriptManager = Page.Master.FindControl("CPScriptManager") myScriptManager.RegisterAsyncPostBackControl(cmdNew),但当我单击控件时它仍然会清除网格,并且不会触发处理事件的函数。
    • 我更新了我的答案,并发布了相关代码和一个虚拟演示的链接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-10
    相关资源
    最近更新 更多