2009-04-16 63 views
1

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

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

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

我检查,它是通过引用而不是副本(我可以告诉)传递。

在搜索控件中有一个updatepanel。产品控制中有一个更新面板。然后为了更好的衡量,在实际的搜索aspx页面中有一个更新面板。

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

这里的秘密是什么?

TIA!

解决

由于杰米井的小费使用的事件。

搜索控件和产品控件仍然有内部更新面板,并且在此特定页面上没有更长的页面。

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

产品控制FYI接受几种不同口味的产品。一系列不同的SKU,产品ID列表,数据库中的命名集合以及最终给定的产品类别。

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

再次感谢!

+2

也许有一点代码会让球滚动。特别是搜索控制如何获得其对产品控制的参考,并且产品代码是否依赖于搜索控制中的任何内容? – 2009-04-16 21:07:15

回答

1

我对AJAX相当陌生,但我不认为用户控件拥有UpdatePanels是个好主意。我还建议你不要让用户控件相互引用;他们应该通过它们的容器控制的事件和方法进行交流。

我为两个用户控件做了一些类似的操作,用于显示主控细节。当从列表中选择一个项目时,主人引发一个事件,包含页面处理该事件,并在细节显示中调用方法以显示所选项目。如果我没有记错,我的第一次尝试在用户控件中有UpdatePanels,我无法做到这一点。在页面上的UpdatePanel中拥有用户控件可以正常工作。

2

我不认为这里有足够的信息来处理,但我最好的猜测是产品控制没有获取数据绑定。您可以尝试从搜索控件(或产品控件中导致DataBind()的某个东西(例如myProductCtrl.Search(value1,value2,value3))调用myProdcutsCtrl.DataBind()。

您可能尝试的另一件事是移除UpdatePanels并查看是否可以正常工作,然后在核心功能发挥作用后再将它们添加回去。

更新:我已经走了,并把一些示例代码在这里工作,我相信完成了你想要的。以下是为节省空间而编写的代码片段,但包含使其运行所需的所有代码。希望这至少会给你一些参考。

事情尝试:

  1. 的EnablePartialRendering =“真|假”设置为false将迫使自然的回传,有利于调试UpdatePanel的问题。
  2. 确保您看到正在加载...出现在您的屏幕上。 (也许太快根据您的开发计算机上)

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(); 
} 

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

+0

嗯...我认为这是非常明确的没有代码,但我猜不是。唯一不会发生的是显示没有被更新。我已经完成了代码,所有的数据都被加载得很好。 – klkitchens 2009-04-16 22:01:09

+0

那么你完美地描述了这个问题,它有时只是细节中的恶魔!在这种情况下,细节可能是代码。 .NET是易变的野兽,时间就是一切! – 2009-04-17 03:29:53

1

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

Outer UpdatePanel 
    SearchControl 
    Search UpdatePanel 
    ProductControl 
    Product UpdatePanel 
     Databound Control 

其中那些更新面板之一实际上是被称为?

我假设如果您使用类似FiddlerFirebug的网络流量检查网络流量(如果您使用的是Firefox),那么您没有看到任何用于产品更新面板的HTML返回?

您是否尝试过做类似:

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

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

默认情况下,如果回发是由一个UpdatePanel制成,只有控制将被更新/重新渲染(这就是所谓的部分页面渲染)。

同时更新/重新渲染其他的UpdatePanel,你必须要么:

  • 设置其UpdateMode属性为Always
  • 添加,使回发到他们的Triggers集合控制

查询this page in MSDN了解详情。

相关问题