在foreach循环内设置用户控件的属性

时间:2009-10-29 17:22:41

标签: c# user-controls webforms

我有一个用户控件,我在多个页面上使用它来显示有关对象的信息。每当我需要使用这个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控件。

3 个答案:

答案 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,那么数据绑定与铸造是阻力最小的路径。

顺便说一下,你上面的方法不起作用,因为:

  1. runat = server无法使用填充ASP.NET控件属性 <%= %>语法 - 这只是有用的 用于纯文本输出,而不是用于 填写对象属性。

  2. 使用数据绑定语法(<%# %>)绝对可以用来填充 在控制属性,但你需要 将控件包装在数据绑定中 容器(如中继器)和电话 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控件。