且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

ASP.NET/AJAX Updatepanel显示两次

更新时间:2023-01-06 22:04:19

解决方案



为什么要动态添加按钮作为触发器。你正在做因为你正在调用一个 AddParameterClick 的自定义事件。



无论你在这个事件中做什么都可以可在 ItemCommand $内完成c $ c> [ ^ ]事件本身。您可以将 ItemCommand 事件声明为异步触发器。



通过RepeaterCommandEventArgs类 [ ^ ],您可以获取有关从中获取命令的行的所有详细信息。



所以,摘要是......

  1. 声明 ItemCommand 像触发器一样...

     <  触发器 >  
    < asp:AsyncPostBackTrigger ControlID = rptParameters EventName = ItemCommand / >
    < / Triggers >

  2. 声明 ItemCommand 直放站。删除 ItemCreated ,这是不再需要的。

     &lt ;   asp:Repeater     runat   =  server    ID   =  rptParameters    EnableViewState   =  true     OnItemCommand   =  rptParameters_ItemCommand   >  



  3. ItemCommand 内,做你想做的事在 AddParameterClick 里面做。


嗯,我知道使用表格有点顽皮(我真的不想在单个页面,内部Web表单的CSS路线上)但是更新面板被创建为div并且与表格混淆并且其中存在问题。



我把桌子换成div和段落后,一切都开始工作了。



故事的寓意:a捷径很少是捷径。


I haven't touched ASP in a long time and I'm starting to remember why!

I have an update panel that contains a repeater, the repeater items contain a button and I want that button as an asynchronous post-back trigger for the update panel.

The update panel looks like this:

<asp:UpdatePanel runat="server" Visible="true" ID="pnlSproc" UpdateMode="Conditional" ChildrenAsTriggers="true">
    <ContentTemplate>
        .
        .
        .
            <asp:Repeater runat="server" ID="rptParameters" EnableViewState="true" OnItemCreated="rptParameters_ItemCreated" >
                <ItemTemplate>
                    <tr>
                        .
                        .
                        .
                        <td>
                            <asp:Button runat="server" ID="btnAddParameter" />
                        </td>
                    </tr>
                </ItemTemplate>
            </asp:Repeater>
        </tr>
    </ContentTemplate>
</asp:UpdatePanel>


The ItemCreated event of the repeater adds the button as an asynchronous trigger ...

protected void rptParameters_ItemCreated(object source, RepeaterItemEventArgs e)
{
    ScriptManager manager = ScriptManager.GetCurrent(this);

    Button button = (Button)e.Item.FindControl("btnAddParameter");

    if (button != null)
    {
        button.Click += AddParameterClick;
        manager.RegisterAsyncPostBackControl(button);
    }
}


When the event fires, all the appropriate events fire as expected but the panel is rendered twice - once in its updated form (higher up the page than it should be) and once in its original form and position.

If I change the RegisterAsyncPostBackControl call to RegisterPostBackControl everything works as I would expect it to but obviously I get a full page postback which I don't want.

Has anyone come across anything similar before? It certainly looks like it's the async postback that's causing the rendering problem (it occurs in both IE and Chrome and my mark-up looks completely valid. I've tried moving the script manager from the page to the master and that has no effect, either.

Solution


Why are you dynamically adding the button as a Trigger. You are doing it because you are calling one custom Event that is "AddParameterClick".

Whatever you are doing inside this Event can be done inside the ItemCommand[^] Event itself. And you can declare ItemCommand Event as a Async Trigger.

Through the RepeaterCommandEventArgs Class[^], you can fetch every details about the Row from which you got the Command.

So, summary is...
  1. Declare the ItemCommand as a Trigger like...
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="rptParameters" EventName="ItemCommand" />
    </Triggers>

  2. Declare ItemCommand for the Repeater. Delete ItemCreated, which is not needed any more.
    <asp:Repeater runat="server" ID="rptParameters" EnableViewState="true" OnItemCommand="rptParameters_ItemCommand" >


  3. Inside the ItemCommand, do what you are trying to do inside the AddParameterClick.


Well, I knew that using tables was a bit naughty (I really didn't want to go down the CSS route for a single page, internal web form) but the update panel gets created as a div and that gets confused with the table and therein lies the problem.

As soon as I changed my table to divs and paragraphs, it all started working.

The moral of the story: a short-cut is rarely a short-cut.