一个用户控件在AJAX回发期间更新另一个?

时间:2009-04-16 20:56:28

标签: asp.net ajax updatepanel

我开发了一个显示产品列表的用户控件,它的效果非常好。然后我将这个用户控件放到另一个用户控件中,该控件允许用户选择不同的标准,产品UC更新以显示这些产品,所有产品都很漂亮,并通过UpdatePanel使用AJAX。

所有工作都很好......然后又有了另一个要求。“搜索”控件需要与产品控件分开(因此可以单独定位)。最初,我认为这没有问题,因为我会给搜索控件一个产品控件的引用,然后它会通过引用而不是直接在控件内部(已被删除)与它通信。

他们确实在说话。但产品控制加载,但拒绝显示。

我检查过它是通过引用传递的,而不是副本(我能说的最好)。

搜索控件中有一个更新面板。产品控件中有一个更新面板。然后,在实际的搜索aspx页面中,有一个更新面板围绕它们。

我尝试将产品控制更新面板设置为条件,然后手动触发.Update()方法。

这里有什么秘密?

TIA!

解决

感谢 Jamie Ide 提示使用活动。

搜索控件和产品控件仍然有内部更新面板,并且不再在此特定页面上显示它们。

Search Control现在会引发一个事件OnSearchResultsUpdated,并在属性中公开找到的项目。页面订阅此事件并获取属性并将它们传递给产品控件,触发器触发产品控件上的.Refresh()方法,该方法只调用其内部更新面板上的.Update()。

产品控制,仅供参考,接受多种不同口味的产品。不同SKU列表,产品ID列表,数据库中的命名集合以及最终给定的产品类别。

我们的设计师需要能够创建一个新页面,将控件放到它上面并设置一些属性和瞧!新网站页面。他们不想要程序员的参与。因此,需要保持控件自包含。幸运的是,我所做的所有更改仍然完全适用于产品控件的其他用途。

非常感谢!

4 个答案:

答案 0 :(得分:2)

我认为没有足够的信息可以在这里使用,但我最好的猜测是产品控件没有得到数据绑定。您可以尝试从搜索控件中调用myProdcutsCtrl.DataBind()(或Product控件中导致DataBind()的内容,例如myProductCtrl.Search(value1,value2,value3)。

您可能尝试的另一件事是删除UpdatePanel并查看是否有效。然后在获得核心功能后再添加它们。

更新:我已经开始并提供了一些在此工作的示例代码,我相信这些代码可以实现您想要的功能。以下是为节省空间而提供的片段,但包含使其运行所需的所有代码。希望这至少可以为您提供参考。

要尝试的事情:

  1. EnablePartialRendering =“true | false”将其设置为false将强制执行自然回发,并且有助于调试UpdatePanel问题。
  2. 确保您在屏幕上看到正在加载... 。 (可能太快,取决于你的开发计算机)
  3. <强> Page.aspx

    <%@ Register Src="~/Product.ascx" TagPrefix="uc" TagName="Product" %>
    <%@ Register Src="~/Search.ascx" TagPrefix="uc" TagName="Search" %>
    

    ...

    <asp:ScriptManager runat="server" ID="sm" EnablePartialRendering="true" />
    Loaded <asp:Label ID="Label1" runat="server"><%= DateTime.Now %></asp:Label>
    
    <asp:UpdateProgress runat="server" ID="progress" DynamicLayout="true">
    <ProgressTemplate><b>Loading...</b></ProgressTemplate>
    </asp:UpdateProgress>
    
    <uc:Search runat="server" ID="search" ProdcutControlId="product" />
    <uc:Product runat="server" ID="product" />
    

    <强> Search.ascx

    <asp:UpdatePanel runat="server" ID="searchUpdate" UpdateMode="Conditional" ChildrenAsTriggers="true">
    <ContentTemplate>
    <p>
        <asp:Label runat="server" AssociatedControlID="filter">Less than</asp:Label>
        <asp:TextBox runat="server" ID="filter" MaxLength="3" />
        <asp:Button runat="server" ID="search" Text="Search" OnClick="SearchClick" />
    </p>
    </ContentTemplate>
    </asp:UpdatePanel>
    

    <强> Search.ascx.cs

        public string ProdcutControlId { get; set; }
        protected void SearchClick(object sender, EventArgs e)
        {
            Product c = this.NamingContainer.FindControl(ProdcutControlId) as Product;
            if (c != null)
            {
                c.Search(filter.Text);
            }
    
        }
    

    <强> Product.ascx

    <asp:UpdatePanel runat="server" ID="productUpdate" UpdateMode="Conditional" ChildrenAsTriggers="false">
    <ContentTemplate>
    <asp:Label runat="server">Request at <%= DateTime.Now %></asp:Label>
    <asp:ListView runat="server" ID="product">
    <LayoutTemplate>
        <ul>
            <li id="itemPlaceHolder" runat="server" />
        </ul></LayoutTemplate>
    <ItemTemplate>
        <li><%# Container.DataItem %></li></ItemTemplate>
    </asp:ListView>
    
    </ContentTemplate>
    </asp:UpdatePanel>
    

    <强> Product.ascx.cs

    IEnumerable<int> values = Enumerable.Range(0, 25);
    public void Search(string val)
    {
        int limit;
        if (int.TryParse(val, out limit))
            product.DataSource = values.Where(i => i < limit);
        else
            product.DataSource = values;
        product.DataBind();
        productUpdate.Update();
    }
    

    代码并不代表最佳做法,只是一个简单的例子!

答案 1 :(得分:1)

如果我理解你,你就有这样的布局:

Outer UpdatePanel
  SearchControl
    Search UpdatePanel
  ProductControl
    Product UpdatePanel
      Databound Control

实际上正在调用哪个更新面板?

我认为如果您使用Firefox检查网络流量时使用的是FiddlerFirebug,那么您是否看不到产品更新面板的任何HTML回来了?

你有没有尝试过这样的事情:

UpdatePanel productUpdate = 
              Page.FindControl("Product UpdatePanel") as UpdatePanel;

if (null != productUpdate){
  productUpdate.Update();
}

答案 2 :(得分:1)

默认情况下,如果从UpdatePanel进行回发,则只会更新/重新呈现该控件(这称为部分页面呈现)。

要同时更新/重新呈现其他UpdatePanel,您必须:

  • 将其UpdateMode属性设置为Always
  • 添加使回发成为其触发器集合的控件

查看this page in MSDN了解详情。

答案 3 :(得分:1)

我对AJAX很新,但我不认为用户控件使用UpdatePanel是个好主意。我还建议你不要让用户控件互相引用;他们应该通过容器控制的事件和方法进行沟通。

我使用两个用户控件执行类似的操作,以显示主控详细信息。当从列表中选择项目时,主控制器引发事件,包含页面处理事件并在详细信息显示上调用方法以显示所选项目。如果我没记错的话,我的第一次尝试在用户控件中有了UpdatePanels,而我无法完成这项工作。在页面上的UpdatePanel中使用用户控件可以正常工作。