简体   繁体   English

ASP.NET:当我单击LinkBut​​ton时,会引发错误的事件

[英]ASP.NET: Wrong event is fired when I click a LinkButton

I have a "cart" Repeater , where every item has a couple of controls in it. 我有一个“购物车” Repeater ,每个项目中都有几个控件。 The ones we're focusing on are two DropDownLists , a LinkButton and a TextBox . 我们关注的是两个DropDownLists ,一个LinkButton和一个TextBox The lists are on one validation group and the button & textbox are on another. 列表在一个验证组中,而按钮和文本框在另一个验证组中。

Both lists have an OnSelectedIndexChanged event handler which does some calculations based on the selections in both DropDownLists . 这两个列表都有一个OnSelectedIndexChanged事件处理程序,该处理程序根据两个DropDownLists的选择进行一些计算。 Both lists also have AutoPostBack="True" . 这两个列表还具有AutoPostBack="True"

The button has an OnClick handler which also does some calculations according to the number in the textbox. 该按钮具有一个OnClick处理程序,该处理程序还会根据文本框中的数字进行一些计算。

I need the calculations to be updated immediately - so I added another data binding for the Repeater - on each event handler 我需要立即更新计算-因此我在每个事件处理程序上为Repeater添加了另一个数据绑定

The problem is - I can't get the value from the TextBox after I click on one of the DropDownLists . 问题是 -单击DropDownLists之一后,无法从TextBox中获取值。 It always comes off as 1. In the background, the OnSelectedIndexChanged event handler fires first , and the buttons' OnClick will fires after it. 它始终关闭为1。在后台, 首先触发OnSelectedIndexChanged事件处理程序,然后在其后触发按钮的OnClick That only happens after I change one of the lists - and it happens every time I click that button from that moment on. 只有在更改列表之一后才会发生这种情况 -从那时起每次单击该按钮都会发生这种情况。 Before that - everything is normal on all controls. 在此之前-所有控件上的一切正常。

What do you think? 你怎么看? Below is some code (I hope it's not too much, I included everything that's taking part) - Thank you very much! 下面是一些代码(我希望它不要太多,我包括了要参与的所有内容)- 非常感谢!

Here's the repeater template: 这是中继器模板:

                <ItemTemplate>
                    <tr>
                        <td class="size"><div><asp:DropDownList runat="server" ID="_selectSize" AutoPostBack="true" OnSelectedIndexChanged="selectChange" EnableViewState="true" TabIndex="<%#Container.ItemIndex%>" ValidationGroup="doNotValidate"></asp:DropDownList></div></td>
                        <td class="material"><div><asp:DropDownList runat="server" ID="_selectMaterial" AutoPostBack="true" OnSelectedIndexChanged="selectChange" EnableViewState="true" TabIndex="<%#Container.ItemIndex%>" ValidationGroup="doNotValidate"></asp:DropDownList></div></td>
                        <td class="quantity">
                            <div>
                                <div class="quantity_container"><asp:TextBox runat="server" ID="_txtAmount" name="quantity_<%#Container.ItemIndex%>" ValidationGroup="vCart"></asp:TextBox></div>
                                <div><asp:LinkButton runat="server" CssClass="refresh" id="_refreshCart" ValidationGroup="vCart"></asp:LinkButton></div>
                            </div>
                        </td>
                    </tr>
                </ItemTemplate>

The Repeater.DataBound() : Repeater.DataBound()

Protected Sub rptCart_ItemDataBound(sender As Object, e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rptCart.ItemDataBound
    If e.Item.ItemType = ListItemType.AlternatingItem OrElse e.Item.ItemType = ListItemType.Item Then
        Dim OrderItem As ProxyMarket.Item = CType(e.Item.DataItem, ProxyMarket.Item)
        Dim btnRemoveProduct As LinkButton = CType(e.Item.FindControl("_removeProduct"), LinkButton)
        Dim btnRefreshCart As LinkButton = CType(e.Item.FindControl("_refreshCart"), LinkButton)
        Dim txtAmount As TextBox = CType(e.Item.FindControl("_txtAmount"), TextBox)
        Dim sizeSelect As DropDownList = CType(e.Item.FindControl("_selectSize"), DropDownList)
        Dim materialSelect As DropDownList = CType(e.Item.FindControl("_selectMaterial"), DropDownList)

        btnRemoveProduct.CommandName = OrderItem.ID
        btnRefreshCart.CommandName = OrderItem.ID
        txtAmount.Text = OrderItem.Units

        AddHandler btnRemoveProduct.Click, AddressOf removeProduct
        AddHandler btnRefreshCart.Click, AddressOf refreshCart

        sizeSelect.DataSource = sizeList
        sizeSelect.DataBind()
        sizeSelect.SelectedIndex = s
        materialSelect.DataSource = materialList
        materialSelect.DataBind()
        materialSelect.SelectedIndex = m
    End If
End Sub

Here is the DropDownLists event handler: 这是DropDownLists事件处理程序:

Protected Sub selectChange(ByVal sender As DropDownList, ByVal e As System.EventArgs)
    Dim listing As New PriceListing
    Dim ddl As DropDownList
    Dim selectedIndex As Integer

    If sender.ID = "_selectSize" Then
        For Each rptrItem As RepeaterItem In rptCart.Items
            ddl = CType(rptrItem.FindControl("_selectMaterial"), DropDownList)
            If ddl.TabIndex = sender.TabIndex Then Exit For
        Next

        For Each listing In artDecoPricing
            If listing.Size = sender.SelectedValue Then Exit For
        Next

        selectedIndex = ddl.SelectedIndex
        s = sender.SelectedIndex
    ElseIf sender.ID = "_selectMaterial" Then
        For Each rptrItem As RepeaterItem In rptCart.Items
            ddl = CType(rptrItem.FindControl("_selectSize"), DropDownList)
            If ddl.TabIndex = sender.TabIndex Then Exit For
        Next

        For Each listing In artDecoPricing
            If listing.Size = ddl.SelectedValue Then Exit For
        Next

        selectedIndex = sender.SelectedIndex
        s = ddl.SelectedIndex
    End If

    Select Case selectedIndex
        Case 0
            Cart.Order.Items(sender.TabIndex).PriceUnit = listing.Canvas
        Case 1
            Cart.Order.Items(sender.TabIndex).PriceUnit = listing.Acrylic
        Case 2
            Cart.Order.Items(sender.TabIndex).PriceUnit = listing.Framed
        Case 3
            Cart.Order.Items(sender.TabIndex).PriceUnit = listing.Alucobond
    End Select

    Cart.SaveOrder()

    s = sender.SelectedIndex
    m = selectedIndex

    rptCart.DataSource = Cart.Order.Items
    rptCart.DataBind()
End Sub

And finally, the LinkButton OnClick handler: 最后, LinkButton OnClick处理程序:

Protected Sub refreshCart(ByVal sender As Object, ByVal e As System.EventArgs)
    Dim btnRefreshCart As LinkButton = CType(sender, LinkButton)
    Dim amountStr As String
    Dim amount As Integer

    amountStr = CType(btnRefreshCart.Parent.FindControl("_txtAmount"), TextBox).Text
    If IsNumeric(amountStr) Then
        amount = CDbl(amountStr)
    Else
        amount = -1
    End If
    amount = IIf(amount > 0, amount, -30)

    For Each Item As ProxyMarket.Item In Cart.Order.Items
        If Item.ID = btnRefreshCart.CommandName Then
            Item.Units = amount
            Cart.Edit_Product(btnRefreshCart.CommandName, amount)
            Exit For
        End If
    Next

    rptCart.DataSource = Cart.Order.Items
    rptCart.DataBind()
End Sub

Thank you :) 谢谢 :)

I found a solution! 我找到了解决方案!

Apparently this is happening because of a viewstate limitation in ASP.NET which causes the OnSelectedIndexChanged to fire on Page_Load regardless if the user actually selected a different value. 显然,这是由于ASP.NET中的视图状态限制而引起的,这导致OnSelectedIndexChanged在Page_Load上触发,无论用户是否实际选择了其他值。

So when the event handler fires, I am checking whether it is the DropDownLists which called me or a different control - that prevents the event from firing when it doesn't need to - and keeps all event handling on the page intact: 因此,当事件处理程序触发时,我正在检查是调用我的DropDownLists还是其他控件-防止不需要时触发该事件-并保持页面上所有事件的处理完好:

Protected Sub selectChange(ByVal sender As DropDownList, ByVal e As System.EventArgs)
    Dim senderClientID = Page.Request.Params.Get("__EVENTTARGET")
    ' Run ONLY if the relevant select control was clicked,
    ' otherwise this is only fired because of ASP.NET limitations,
    ' and will screw up the original event:
    If senderClientID.IndexOf("_selectSize") <> -1 Or senderClientID.IndexOf("_selectMaterial") <> -1 Then
        'do stuff

I know this has already been answered but I was having a very similar problem, with a completely different solution and as this is the first post that appeared in google I thought I would add it here. 我知道这已经得到了回答,但是我遇到了一个非常相似的问题,采用了完全不同的解决方案,这是出现在Google上的第一篇文章,我想我会在这里添加它。

I had a link button and when clicking it, but only in IE9, it appeared to activate another button on the page and call it's event rather than it's own. 我有一个链接按钮,当单击它时,但仅在IE9中,它似乎激活了页面上的另一个按钮,并称其为事件而不是其本身。

After much messing about and googling, I realised that it wasn't just my button that was activating the other button it was if I clicked anywhere in a particular section of my page. 经过一番混乱和谷歌搜索之后,我意识到激活按钮的不仅是我的按钮,还包括单击页面特定部分中的任何地方。

I eventually found the problem after completely stripping down my page. 完全删除我的页面后,我最终发现了问题。 It was this: 就是这样的:

   <label style="width: 100%" />

an empty label tag. 空标签标签。 Once deleted all was fine. 一旦删除,一切都很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM