2009-10-29 75 views
5

我有一个用户控件,我在多个页面上使用它来显示有关对象的信息。无论何时我需要使用此用户控件,我都会调用一个名为Display(在usercontrol上)的方法并传入一些值。在foreach循环内的用户控件上设置属性

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"/> 
<% } %> 

类别对象具有我否则将传递到显示方法的方法和属性。那么我将如何正确设置值?

我试图在用户控件公开场合的属性,只是设置它们以这样的方式

<uc:ItemsControl Items="<%# c.Items %>" 
       OtherProperty="<%# c.GetProperty() %>" 
       runat="server"/> 

这是不行的,因为性能得到派往是空的。如果我使用<%=那么它不起作用,实际上会抛出一个错误,因为它不能识别'c'(除非我离开runat =“server”,那么它至少可以编译,它仍然不会工作。

什么是做到这一点的正确方法

编辑:?另外,中继器控制可能使这更容易的数据绑定,但我宁愿避免使用任何.NET控件

回答

0

虽然Justin Grant's answer可能会甲肝工作得很好,我们决定只加载用户控制和调用DisplayResults方法。

<% ((UserControlType)LoadControl("~/pathToUserControl.ascx")) 
     .DisplayResults(ItemName, ItemList)); %> 

这不是完整的代码,但它是需要解决我在问题中解决的问题。通过这种方式加载用户控件,我们可以设置我们需要的属性,并使用正确的信息显示uesr控件。

10

在WebForms页面中,通常通过使用DataBinding来处理,而不是使用foreach循环,您可以使用Repeater控件,将其DataSource属性设置为<%#Categories%>,然后在拿铁咖啡中使用数据绑定语法除了c之外,您需要将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> 

唯一需要注意的是你需要somwhere调用的Repeater的DataBind()方法,通常是在Page_Load方法。个人而言,我总是发现数据绑定是一种痛苦 - 对于我来说,调用数据绑定和调用数据绑定的需要都比您上面尝试的foreach方法更不自然。这可能是我最喜欢关于ASP.NET MVC的事情 - 您的MVC Views可以更容易地使用更直接的迭代foreach模型,恕我直言。也就是说,如果你必须坚持使用WebForms,那么数据绑定是一条阻力最小的路径。

顺便说一句,你的方法上面没有工作,因为:

  1. RUNAT = ASP.NET服务器控件属性不能使用 <%= %> syntax--这是唯一有用的 为纯文本输出缭绕,不为 填写对象属性。使用数据绑定语法(<%# %>

  2. 绝对可以用于控制特性,以填补 ,但你需要 来包装数据绑定 容器中的控制(如中继器),并调用 的DataBind()为了得到 替换发生。

+1

重复器可能是正确的方式,但我们尽量避免使用.NET控件,并倾向于生成HTML。 – Brandon 2009-10-29 18:12:53

+0

是的,我也是 - 我也发现循环发射HTML方法更直接。这就是为什么我喜欢ASP.NET MVC。但对于Web窗体,如果您已经在使用自己的自定义控件并需要填充其属性,尤其是在循环中,则使用数据绑定是最简单的方法。出于好奇,为什么要避免使用asp.net的内置控件?这是一个与绩效相关的问题还是其他问题?中继器控制非常简单,并且速度很快,并且不会导致视图状态或其他类似情况。中继器可以像伪装成控件的foreach循环一样起作用。 – 2009-10-29 20:26:08

+0

这更多的是一致性/性能问题。我的老板最初从项目中的.NET控件移开,因为控件/ AjaxToolKit对我们所需要的太重了,所以采用了纯粹的HTML/jQuery方法。如果一切都失败了,我可以投入一个中继器,我只是想知道是否有任何方式使用我们已经开始的路径来做到这一点。 – Brandon 2009-10-29 20:32:43

1

我知道这是旧的,但我发现这个线程很快通过谷歌,所以我只需输入这个。

我刚刚注意到,当帮助一个同事,你可以这样做与UserControls在foreach。请注意,我只通过他的示例对其进行了测试。

<% foreach (var c in Categories) { %> 
     <uc:ItemsControl runat="server" ID="ucItem"/> 
<% 
ucItem.PropertyToChange = c.Property; 
} %> 

如果这并不适用于你ATLEAST这可能是别人。

+1

您需要在调用控件之前设置属性。但除此之外,如果它是一个循环中使用的控件的单个实例的简单情况,则很方便。 – Reuben 2014-02-12 23:39:06