Bra*_*don 5 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
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,但现在我需要在aspx页面的foreach循环中使用此控件.
<% foreach (var c in Categories) { %>
<uc:ItemsControl runat="server"/>
<% } %>
Run Code Online (Sandbox Code Playgroud)
categories对象具有我将传递给Display方法的方法和属性.那么我该如何正确设置值呢?
我尝试在用户控件上公开属性,并以这种方式设置它们:
<uc:ItemsControl Items="<%# c.Items %>"
OtherProperty="<%# c.GetProperty() %>"
runat="server"/>
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为发送的属性是空的.如果我使用<%=然后它不起作用,实际上抛出一个错误,因为它不识别'c'(除非我脱掉runat ="server"然后它至少会编译,它仍然无法工作但.
这样做的正确方法是什么?
编辑:此外,转发器控件可能使数据绑定更容易,但我宁愿避免使用任何.NET控件.
Jus*_*ant 10
在WebForms页面中,通常使用DataBinding处理此方法.您可以使用Repeater控件,将其DataSource属性设置为<%#Categories%>,然后在上面的示例中使用数据绑定语法,而不是foreach循环,除了代替之外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>
Run Code Online (Sandbox Code Playgroud)
唯一需要注意的是,您需要调用Repeater somwhere的DataBind()方法,通常在Page_Load方法中.
就个人而言,我总是发现数据绑定是一种痛苦 - 对于我而言,转换和调用数据绑定的需要比我上面尝试的foreach方法更不自然.这可能是我最喜欢ASP.NET MVC的东西 - 你的MVC视图可以更容易地使用更简单的foreach迭代模型,恕我直言.也就是说,如果你必须坚持使用WebForms,那么数据绑定与铸造是阻力最小的路径.
顺便说一下,你的上述方法不起作用,因为:
runat = server无法使用<%= %>语法填充ASP.NET控件属性 -
这仅对纯文本输出有用,而不是用于填充对象属性.
使用数据绑定语法(<%# %>)绝对可以用来填充控件属性,但是你需要将控件包装在数据绑定容器(如Repeater)中并调用DataBind()以便进行替换.
虽然Justin Grant 的答案可能效果很好,但我们决定只加载用户控件并调用 DisplayResults 方法。
<% ((UserControlType)LoadControl("~/pathToUserControl.ascx"))
.DisplayResults(ItemName, ItemList)); %>
Run Code Online (Sandbox Code Playgroud)
这不是完整的代码,但它是解决我在问题中解决的问题所需的代码。通过这种方式加载用户控件,我们可以设置所需的属性并显示带有正确信息的 uesr 控件。