1

在过去的几天里,我一直在用头撞墙,试图让这个场景发挥作用。

<asp:UpdatePanel>在一个页面上有一个外部触发器并包含一个 Telerik RadListView

<asp:UpdatePanel runat="server" ID="RationUpdatePanel" UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
    <telerik:RadListView ID="RationListView runat="server"
        DataSourceId="RationDataSource" 
        OnItemCanceling="ItemCancelingHandler"
        OnItemEditing="ItemEditingHandler"
        OnItemUpdating="ItemUpdateHandler">
        <LayoutTemplate>
            <table>
               <thead>
                   <tr>...</tr>
               </thead>
               <tbody>
                   <tr id="itemPlaceHolder" runat="server"/>
               </tbody>
            </table>
        </LayoutTemplate>
        <ItemTemplate>
            <tr>
               <td>
                   <asp:LinkButton ID="EditButton" runat="server" CausesValidation="False" CommandName="Edit" Text="Edit" ToolTip="Edit" />&nbsp;
                   <asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False" CommandName="Delete" Text="Delete" ToolTip="Delete" />
               </td>
               <td>...</td>
             </tr>
        </ItemTemplate>
        <EditItemTemplate>
            <tr>
               <td>
                   <asp:LinkButton ID="SaveButton" runat="server" CausesValidation="False" CommandName="Save" Text="Save" ToolTip="Save" />&nbsp;
                   <asp:LinkButton ID="CancelButton" runat="server" CausesValidation="False" CommandName="Cancel" Text="Cancel" ToolTip="Update" />
               </td>
               <td>...</td>
             </tr>
        </EditItemTemplate>
    </telerik:RadListView>
</ContentTemplate>
<Triggers>
    <asp:AsyncPostBackTrigger ControlID="UseRationButton" EventName="Click" />
</Triggers>
</UpdatePanel>

后面的代码如下所示:

    protected void RationListView_ItemEditing(object sender, RadListViewCommandEventArgs e)
    {
        ((RadListViewDataItem)e.ListViewItem).Edit = true;
    }

    protected void RationListView_ItemCanceling(object sender, RadListViewCommandEventArgs e)
    {
        RationListView.ClearEditItems();
        ((RadListViewDataItem)e.ListViewItem).Edit = false;
    }

单击EditButtonCancelButton产生预期事件并调用 ObjectDataSource 例程以重新绑定列表,但更新面板未刷新。从事件处理程序调用RationUpdatePanel.Update()不会改变这种情况。该代码在更新面板之外正常工作:模式更改并显示来自其他模板的按钮。

在任一情况下,单击外部触发器都会显示列表。

更新:我为 beginRequest 和 endRequest 在浏览器中的 PageManager 类中添加了几个 javascript 回调。这些只是在事件发生时显示警报。

该页面包含几个元素,基本上看起来像这样(细节省略):

<div>
    <div>
        <asp:DropDownList ID="RationDdl"/>
        <asp:Button ID="UseRationButton"/>
    </div>
    <div>
        <asp:DropDownList ID="AnimalGroupDdl"/>
        <asp:UpdatePanel ID="AnimalWeightUpdatePanel"/>
            <ContentTemplate>
                <asp:DropDownList ID="AnimalWeightDdl"/>
            </ContentTemplate>
        </asp:UpdatePanel>
    </div>
</div>
<div>
    <telerik:RadListBox>
    </telerik:RadListBox>
</div>
<div>
    <asp:UpdatePanel ID="FeedPreviewUpdatePanel">
        <ContentTemplate>
            <asp:Repeater>
            </asp:Repeater>
        </ContentPanel>
    </asp:UpdatePanel>
</div>  
<div>
    <!-- this contains the update panel shown above -->
</div>

UseFeedRationButton一个 div 中的 是RationUpdatePanel. AnimalGroupDdl是 的外部触发器AnimalWeightUpdatePanel。SelectedIndexChanged 事件的处理程序会AnimalGroupDdl填充AnimalWeightDdl所选组的可用权重等级。它与RationUpdatePanelor没有交互作用FeedPreviewUpdatePanel

这是 的标记UseRationButton

            <asp:Button ID="UseRationButton" runat="server" 
                Text="Use This Ration" 
                OnClick="UseRationButton_Click" 
                CausesValidation="true" 
                ValidationGroup="UseRation" 
                UseSubmitBehavior="false">
            </asp:Button>&nbsp;

这是背后的代码:

    protected void UseRationButton_Click(object sender, EventArgs e)
    {
        string text = this.RationDdl.SelectedItem.Text;
        this.RationNameLabel.Text = text;
        this.RationDataSource.SelectParameters["RationId"].DefaultValue = this.RationDdl.SelectedValue;
    }

我一直在测试两种情况:

1) 选择一个口粮RationDdl并点击UseRationButton 2) 选择一个动物组,然后执行场景 1。

在场景 1 中,异步回发由客户端 asp.net 代码启动,并且按钮事件由服务器端处理。RationListView 已填充,但客户端 endRequest 代码从未执行(不显示警报)。随后单击 RadListView 中的控件会触发异步回发,但列表的状态不会更改,客户端的 endRequest 代码也不会执行。

在场景 2 中,启动异步回发,事件在服务器端处理并AnimalWeightDdl填充。在这种情况下执行客户端 endRequest 代码(显示警报)。在此选择配给并单击使用配给按钮启动回发之后,填充列表视图并执行 endRequest 代码。在他单击列表视图中的按钮时,会启动异步回发,更改列表的状态并执行 endRequest 代码。

我的工作理论是,某些东西导致客户端上的页面请求管理器类的状态变得模糊,但我无法弄清楚是什么原因造成的。

4

2 回答 2

0

首先,如果您使用telerik rad control,我建议您将您的更改asp:buttontelerik:RadButton.
这是示例

  <telerik:RadButton ID="v" runat="server" Text="Use This Ration"
         AutoPostBack="true" 
  ValidationGroup="UseRation" OnClick="UseRationButton_Click">
  </telerik:RadButton>


  protected void UseRationButton_Click(object sender, EventArgs e)
    {
     string text = this.RationDdl.SelectedItem.Text;
    this.RationNameLabel.Text = text;
    this.RationDataSource.SelectParameters["RationId"].DefaultValue = this.RationDdl.SelectedValue;
    }

请注意,您应该添加AutoPostBack="true"到您的 radButton 中。
此链接MSDN Reference1MSDN Reference2将显示使用更新面板的详细信息。

于 2013-08-10T04:09:23.710 回答
0

我在周五晚些时候和周六早上所做的研究为这个问题提供了答案。

我在 endRequest 事件中附加了一些代码,Sys.WebForms.PageRequestManager它更新了一个文本框,其中包含新口粮的临时标题。代码如下所示:

    ///
    /// reregister the change handlers after reloading the animal weight ddl and create a 
    /// temporary name for the ration based on animal choice and weight.
    ///
    function animalWeightDdlOnLoad() {
        var ddl = document.getElementById("<%= AnimalWeightDdl.ClientID %>");

        //
        // add event handler in a browser agnostic fashion
        //
        if (ddl.addEventListener) {
            ddl.addEventListener("change", animalWeightDdlOnChange);
        }
        else if (ddl.attachEvent) {
            ddl.attachEvent("onchange", animalWeightDdlOnChange);
        }
        else {
            ddl.onchange = animalWeightDdlOnChange;
        }

        animalWeightDdlOnChange();
    }

animalWeightDdlOnChange()参考了动物体重ddl的选项列表:

    ///
    /// create a temporary name for the ration
    ///
    function animalWeightDdlOnChange() {
        var ddl1 = document.getElementById("<%= AnimalGroupDdl.ClientID %>");
        var ddl2 = document.getElementById("<%= AnimalWeightDdl.ClientID %>");
        var text = document.getElementById("<%= RationNameText.ClientID %>");
        text.value = ddl1.options[ddl1.selectedIndex].text + ' ' + ddl2.options[ddl2.selectedIndex].text + ' - Copy';
    }

但是,如果尚未填充列表,则对选项的引用会导致停止 endRequest 处理的错误。我没有在每个异步请求上运行此代码,而是将其更改为动物组 ddl 上更改事件的处理程序,如下所示:

    function animalGroupDdlOnSelectedChanged() {
        //
        // add a handler for the endRequest event which will be triggered by
        // fetching the contents of the weight ddl.
        //
                         Sys.WebForms.PageRequestManager.getInstance().add_endRequest(animalWeightDdlOnLoad);
    }

然后在animalWeightDdlOnLoad()请求运行后,我添加了一行来删除处理程序。这确保了权重 ddl 的更改处理程序仅在填充列表后才运行。问题解决了。但以防万一,我添加了对动物重量 ddl 选项列表长度的检查。

因此,即使看似无辜的 javascript 也会在浏览器中弄乱您的异步请求处理。

于 2013-08-12T14:54:17.770 回答