我开发了一个显示产品列表的用户控件,它的效果非常好。然后我将这个用户控件放到另一个用户控件中,该控件允许用户选择不同的标准,产品UC更新以显示这些产品,所有产品都很漂亮,并通过UpdatePanel使用AJAX。
所有工作都很好......然后又有了另一个要求。“搜索”控件需要与产品控件分开(因此可以单独定位)。最初,我认为这没有问题,因为我会给搜索控件一个产品控件的引用,然后它会通过引用而不是直接在控件内部(已被删除)与它通信。
他们确实在说话。但产品控制加载,但拒绝显示。
我检查过它是通过引用传递的,而不是副本(我能说的最好)。
搜索控件中有一个更新面板。产品控件中有一个更新面板。然后,在实际的搜索aspx页面中,有一个更新面板围绕它们。
我尝试将产品控制更新面板设置为条件,然后手动触发.Update()方法。
这里有什么秘密?
TIA!
解决
感谢 Jamie Ide 提示使用活动。
搜索控件和产品控件仍然有内部更新面板,并且不再在此特定页面上显示它们。
Search Control现在会引发一个事件OnSearchResultsUpdated,并在属性中公开找到的项目。页面订阅此事件并获取属性并将它们传递给产品控件,触发器触发产品控件上的.Refresh()方法,该方法只调用其内部更新面板上的.Update()。
产品控制,仅供参考,接受多种不同口味的产品。不同SKU列表,产品ID列表,数据库中的命名集合以及最终给定的产品类别。
我们的设计师需要能够创建一个新页面,将控件放到它上面并设置一些属性和瞧!新网站页面。他们不想要程序员的参与。因此,需要保持控件自包含。幸运的是,我所做的所有更改仍然完全适用于产品控件的其他用途。
非常感谢!
答案 0 :(得分:2)
我认为没有足够的信息可以在这里使用,但我最好的猜测是产品控件没有得到数据绑定。您可以尝试从搜索控件中调用myProdcutsCtrl.DataBind()(或Product控件中导致DataBind()的内容,例如myProductCtrl.Search(value1,value2,value3)。
您可能尝试的另一件事是删除UpdatePanel并查看是否有效。然后在获得核心功能后再添加它们。
更新:我已经开始并提供了一些在此工作的示例代码,我相信这些代码可以实现您想要的功能。以下是为节省空间而提供的片段,但包含使其运行所需的所有代码。希望这至少可以为您提供参考。
要尝试的事情:
<强> 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检查网络流量时使用的是Fiddler或Firebug,那么您是否看不到产品更新面板的任何HTML回来了?
你有没有尝试过这样的事情:
UpdatePanel productUpdate =
Page.FindControl("Product UpdatePanel") as UpdatePanel;
if (null != productUpdate){
productUpdate.Update();
}
答案 2 :(得分:1)
默认情况下,如果从UpdatePanel进行回发,则只会更新/重新呈现该控件(这称为部分页面呈现)。
要同时更新/重新呈现其他UpdatePanel,您必须:
查看this page in MSDN了解详情。
答案 3 :(得分:1)
我对AJAX很新,但我不认为用户控件使用UpdatePanel是个好主意。我还建议你不要让用户控件互相引用;他们应该通过容器控制的事件和方法进行沟通。
我使用两个用户控件执行类似的操作,以显示主控详细信息。当从列表中选择项目时,主控制器引发事件,包含页面处理事件并在详细信息显示上调用方法以显示所选项目。如果我没记错的话,我的第一次尝试在用户控件中有了UpdatePanels,而我无法完成这项工作。在页面上的UpdatePanel中使用用户控件可以正常工作。