我有一个用户控件,用于显示搜索结果.显示的每个结果的HTML将根据显示的结果类型而变化:"联系人"以一种方式显示,"新闻文章"显示在另一种中,等等.大约有10种不同类型的结果都被标记出来当他们使用HTML时会有所不同 - 所以我需要大约10个不同的模板用于个别结果,我可以根据显示的当前项目进行选择.
我用a asp:Repeater来显示结果,但我不知道如何选择合适的模板asp:Repeater <ItemTemplate>.理想情况下,我希望ASP根据通过searchResultsRepeater.DataSource- 传入的对象类型选择合适的模板使用- 但不幸的是我不能使用switch on type(请参阅此博客条目,了解C#switch on type).但是,我可以通过枚举值来显示所显示的结果类型.
在后端C#代码,我有一个抽象内嵌SearchResult类,并且该类的孩子喜欢ContactSearchResult,NewsArticleSearchResult等searchResultsRepeater.DataSource将被绑定到List<SearchResult>.每个字段都SearchResult包含一个ResultListingType type字段,用于显示要显示的列表类型.
我的第一次尝试是这样的:
<asp:Repeater ID="searchResultsRepeater" runat="server">
<ItemTemplate>
<div class="item">
<% switch (DataBinder.Eval(Container.DataItem, "type")) { %>
<% case ResultListingType.CONTACT: %>
<p><%# DataBinder.Eval(Container.DataItem, "firstName") %></p>
<p><%# DataBinder.Eval(Container.DataItem, "lastName") %></p>
<% break; %>
<% case ResultListingType.NEWS: %>
<p><%# DataBinder.Eval(Container.DataItem, "newsHeadline") %></p>
<p><%# DataBinder.Eval(Container.DataItem, "newsDate") %></p>
<% break; %>
<% Case AnotherTypeOfListing1: %>
<% Case AnotherTypeOfListing2: %>
<% Case AnotherTypeOfListing3: %>
<% Case AnotherTypeOfListing4: %>
<% Case AnotherTypeOfListing5: %>
<% etc... %>
<% } %>
</div>
</ItemTemplate>
</asp:Repeater>
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不起作用:
<%# ... %>括号内给出"无效表达术语" .<% ... %>括号内给出"名称"容器"当前上下文中不存在" .我找到了一些对于如何更改asp:repeater中使用的ItemTemplate有用的东西?.然后我尝试了类似的东西:
<asp:Repeater ID="searchResultsRepeater" runat="server">
<ItemTemplate>
<div class="item">
<asp:PlaceHolder ID="newsResultListing" runat="server">
<p><%# DataBinder.Eval(Container.DataItem, "newsHeadline") %></p>
<p><%# DataBinder.Eval(Container.DataItem, "newsDate") %></p>
</asp:PlaceHolder>
<asp:PlaceHolder ID="contactResultListing" runat="server">
<p><%# DataBinder.Eval(Container.DataItem, "firstName") %></p>
<p><%# DataBinder.Eval(Container.DataItem, "lastName") %></p>
</asp:PlaceHolder>
</div>
</ItemTemplate>
</asp:Repeater>
Run Code Online (Sandbox Code Playgroud)
在我的ItemDataBound事件中,我做了:
Control newsResultListing = e.Item.FindControl("newsResultListing");
newsResultListing.Visible = false;
Control contactResultListing = e.Item.FindControl("contactResultListing");
contactResultListing.Visible = false;
switch (item.type)
{
case ResultListingType.CONTACT:
contactResultListing.Visible = true;
break;
case ResultListingType.NEWS:
newsResultListing.Visible = true;
break;
default:
throw new Exception("Unknown result listing type");
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不起作用,因为即使我设置了ASP,ASP似乎仍然在运行PlaceHolder的内容Visible = false.我收到错误"DataBinding:'usercontrols_ResultsListing + ContactResultsListing'不包含名为'newsHeadline'的属性" - 即newsResultListingPlaceHolder仍然在寻找"newsHeadline"字段,即使结果列表中不存在该字段正在显示的类型.
实际上我已经throw new Exception("e");在我的ItemDataBound中尝试了一个快速测试,看起来甚至在控制流到达ItemDataBound方法之前就抛出了"DataBinding"错误,因此我无法在那里做任何事情来避免这个错误.
我想我可以将每个字段添加到父类中,并将大部分字段留给我的孩子,但这看起来真的很难看.
有没有办法让这个工作,或更容易的方式来改变我的ItemTemplate基于我正在迭代的Container.DataItem的类型?我对ASP很陌生,所以我可能会错过一些简单的东西.:)
Geo*_*rge 14
好的,我想我找到了一个解决方案 - 我已经创建了多个额外的用户控件,每个用户控件对应一种类型的搜索结果.这些控件中的每一个都为其相应类型的搜索结果定义HTML模板.
我的asp:Repeater内容绝对没有ItemTemplate:
<asp:Repeater ID="searchResultsRepeater" runat="server">
<ItemTemplate>
<%-- empty template: we insert usercontrols in the ItemDataBound --%>
</ItemTemplate>
</asp:Repeater>
Run Code Online (Sandbox Code Playgroud)
List<SearchResultData>我asp:Repeater像以前一样绑定到my ,并且在此列表之前包含SearchResultData基于要显示的结果类型的更具体的子类型.
在我的ItemDataBound处理程序中,我根据数据类型实例化其中一个用户控件e.Item.DataItem,然后将该用户控件插入到转发器中:
var aspxItem = e.Item;
var dataItem = (SearchResultData) e.Item.DataItem;
if (dataItem is ContactSearchResult.ContactSearchResultData)
{
var contactSearchResultUC = LoadControl("~/UserControls/ResultsListingSearchResult/ContactSearchResult.ascx") as ASP.ContactSearchResult;
contactSearchResultUC.data = (ContactSearchResult.ContactSearchResultData)dataItem;
aspxItem.Controls.Add(contactSearchResultUC);
}
else if (dataItem is NewsArticleSearchResult.NewsArticleSearchResultData)
{
var newsArticleSearchResultUC = LoadControl("~/UserControls/ResultsListingSearchResult/NewsArticleSearchResult.ascx") as ASP.NewsArticleSearchResult;
newsArticleSearchResultUC.data = (NewsArticleSearchResult.NewsArticleSearchResultData)dataItem;
aspxItem.Controls.Add(newsArticleSearchResultUC);
}
...etc
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18227 次 |
| 最近记录: |