我有一个用户控件,我在多个页面上使用它来显示有关对象的信息。每当我需要使用这个usercontrol时,我调用一个名为Display的方法(在usercontrol上)并传入一些值。
public void Display(string name, List<Items> items)
{
// Set a few protected properties so I can display values from the aspx page
}
这很好用,但现在我需要在aspx页面的foreach循环中使用这个控件。
<% foreach (var c in Categories) { %>
<uc:ItemsControl runat="server"/>
<% } %>
categories对象具有我将传递给Display方法的方法和属性。那么我该如何正确设置值?
我尝试将用户控件上的属性设置为public,并以这种方式设置它们:
<uc:ItemsControl Items="<%# c.Items %>"
OtherProperty="<%# c.GetProperty() %>"
runat="server"/>
这不起作用,因为发送的属性为空。如果我使用&lt;%=然后它不起作用并且实际上抛出错误,因为它不识别'c'(除非我脱掉runat =“server”然后它至少会编译,它仍然无法工作虽然。
这样做的正确方法是什么?
编辑:此外,转发器控件可能会使数据绑定更容易,但我更愿意避免使用任何.NET控件。
答案 0 :(得分:10)
在WebForms页面中,通常使用DataBinding处理此方法。您可以使用Repeater控件,将其DataSource属性设置为<%#Categories%>
,然后在上面的示例中使用数据绑定语法,而不是c
,而不是foreach循环。 ,您需要将Container.DataItem
转换为控件中的正确类型。像这样:
<%@ Page Language="C#" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
CategoriesList.DataBind();
}
class Category
{
public string CategoryName { get; set; }
public string GetProperty() { return CategoryName; }
public string[] Items { get { return new string[] {CategoryName + " 1", CategoryName + " 2"}; } }
}
Category[] Categories = new Category[]
{
new Category { CategoryName = "Shorts" },
new Category { CategoryName = "Socks" },
new Category { CategoryName = "Shirts" },
};
</script>
<html>
<body>
<asp:Repeater runat="server" ID="CategoriesList" DataSource="<%# Categories %>">
<ItemTemplate>
<uc:ItemsControl
Items="<%# ((Category)(Container.DataItem)).Items %>"
OtherProperty="<%# ((Category)(Container.DataItem)).GetProperty() %>"
runat="server"/>
</ItemTemplate>
</asp:Repeater>
</body>
</html>
唯一需要注意的是,您需要调用Repeater somwhere的DataBind()方法,通常使用Page_Load
方法。
就个人而言,我总是发现数据绑定是一种痛苦 - 对于我来说,转换和调用数据绑定的需要比我上面尝试的foreach方法更不自然。这可能是我最喜欢ASP.NET MVC的东西 - 你的MVC视图可以更容易地使用更简单的foreach迭代模型,恕我直言。也就是说,如果你必须坚持使用WebForms,那么数据绑定与铸造是阻力最小的路径。
顺便说一下,你上面的方法不起作用,因为: runat = server无法使用填充ASP.NET控件属性
<%= %>
语法 - 这只是有用的
用于纯文本输出,而不是用于
填写对象属性。
使用数据绑定语法(<%# %>
)绝对可以用来填充
在控制属性,但你需要
将控件包装在数据绑定中
容器(如中继器)和电话
DataBind()以获得
替换发生。
答案 1 :(得分:1)
我知道这已经过时了,但我通过谷歌发现这个帖子很快,所以我只需输入此内容。
我刚刚注意到在帮助一位同事时你可以使用foreach中的UserControl来做这样的事情。请注意,我只是通过他的例子来测试它。
<% foreach (var c in Categories) { %>
<uc:ItemsControl runat="server" ID="ucItem"/>
<%
ucItem.PropertyToChange = c.Property;
} %>
如果这不适合您,至少可能适用于其他人。
答案 2 :(得分:0)
虽然Justin Grant's answer可能很好用,但我们决定只加载用户控件并调用DisplayResults方法。
<% ((UserControlType)LoadControl("~/pathToUserControl.ascx"))
.DisplayResults(ItemName, ItemList)); %>
这不是完整的代码,但它是解决我在问题中解决的问题所需要的。通过这种方式加载用户控件,我们可以设置我们需要的属性,并使用正确的信息显示uesr控件。