我创建了一个显示搜索结果的SearchResults
控件。此控件具有重复元素(显示结果),但也包含我已针对此问题删除的其他元素。
目前在以下示例中DataItem
无法解析。我试图弄清楚如何使DataItem
可解析,以便我可以通过以下方式使用此控件:
<Controls:SearchResults runat="server" id="Results">
<RowHeaderTemplate>
<tr>
<td>User ID</td>
</tr>
</RowHeaderTemplate>
<RowItemTemplate>
<tr>
<td>
<%#((Models.User)Container.DataItem).ID %>
</td>
</tr>
</RowItemTemplate>
</Controls:SearchResults>
以这种方式使用:
var searchResults = GetSearchResults();
Results.DataSource = searchResults ;
Results.DataBind();
[System.ComponentModel.DefaultBindingProperty("DataSource")]
public partial class Search : UserControl
{
[PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(TemplateControl))]
public ITemplate RowHeaderTemplate { get; set; }
[PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(TemplateControl))]
public ITemplate RowItemTemplate { get; set; }
public IEnumerable<object> DataSource { private get; set; }
private bool DataBindingComplete { get; set; }
public override void DataBind()
{
if (DataBindingComplete) return;
foreach (var obj in DataSource)
{
var newControl = new PlaceHolder();
RowItemTemplate.InstantiateIn(newControl);
RowItemContainer.Controls.Add(newControl);
}
DataBindingComplete = true;
base.DataBind();
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Visible) return;
OnInit(e);
if (RowHeaderTemplate != null)
{
RowHeaderTemplate.InstantiateIn(RowHead);
}
}
}
使用标记:
<asp:PlaceHolder runat="server" ID="Wrapper">
<h2>Results</h2>
<table border="1">
<asp:PlaceHolder runat="server" ID="RowHead"/>
<asp:Placeholder runat="server" Visible='<%#TotalResults == 0 %>'>
<tr>
<td colspan="100">
No results returned!
</td>
</tr>
</asp:Placeholder>
<asp:Placeholder runat="server" ID="RowItemContainer" Visible='<%#TotalResults > 0 %>'>
</asp:PlaceHolder>
</table>
</asp:PlaceHolder>
请注意,这是一个精简的示例,只需使用Repeater
控件代替它就不够了。
答案 0 :(得分:1)
问题是Search控件的RowItemTemplate属性的TemplateContainer属性引用了TemplateControl,它没有DataItem属性。而不是使用TemplateControl,创建一个具有DataItem属性的SearchItem控件:
public class SearchItem : Control, INamingContainer
{
public object DataItem { get; set; }
}
在Search类中,更改RowItemTemplate属性的TemplateContainer属性,使其引用SearchItem而不是TemplateControl:
[PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(SearchItem))]
public ITemplate RowItemTemplate { get; set; }
此外,在DataBind中实例化SearchItem而不是PlaceHolder:
var newControl = new SearchItem { DataItem = obj };
这些是让您的示例工作所需的最小更改。但是,您的自定义控件不会自动在回发中保留项目。要实现该功能,我建议您研究Repeater class的源代码。