Установка свойств для пользовательского элемента управления внутри цикла foreach - PullRequest
5 голосов
/ 29 октября 2009

У меня есть пользовательский элемент управления, который я использую на нескольких страницах для отображения информации об объекте. Всякий раз, когда мне нужно использовать этот usercontrol, я вызываю метод Display (on usercontrol) и передаю некоторые значения.

public void Display(string name, List<Items> items)
{
    // Set a few protected properties so I can display values from the aspx page
}

Это работает нормально, но теперь мне нужно использовать этот элемент управления внутри цикла foreach на странице aspx.

<% foreach (var c in Categories) { %>
      <uc:ItemsControl runat="server"/>
<% } %>

У объекта категорий есть методы и свойства, которые я бы иначе передал в метод Display. Так как бы мне правильно установить значения?

Я попытался сделать свойства пользовательского элемента управления общедоступными и просто установить их следующим образом:

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

Это не работает, потому что отправляемые свойства пусты. Если я использую <% =, тогда он не работает и на самом деле выдает ошибку, потому что не распознает 'c' (если я не уберу runat = "server", то он, по крайней мере, скомпилируется, но все равно не будет работать . </p>

Как правильно это сделать?

Редактировать: Кроме того, элемент управления повторителем может упростить привязку данных, но я бы предпочел избегать использования любых элементов управления .NET.

Ответы [ 3 ]

10 голосов
/ 29 октября 2009

На странице 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>

Единственное предостережение: вам нужно вызвать метод DataBind () Repeater, где-нибудь, обычно в методе Page_Load.

Лично я всегда считал, что привязка данных - это боль - и приведение, и необходимость вызывать привязку данных кажутся мне гораздо менее естественными, чем метод foreach, который вы пробовали выше. Это, наверное, то, что мне больше всего нравится в ASP.NET MVC - ваши MVC Views могут гораздо проще использовать модель итерации foreach, которая намного проще, ИМХО. Тем не менее, если вам нужно придерживаться WebForms, привязка данных с приведением является путем наименьшего сопротивления.

Кстати, ваши подходы выше не сработали, потому что:

  1. runat = свойства элемента управления ASP.NET сервера не могут быть заполнены с помощью <%= %> синтаксис - это только полезно для вывода простого текста, не для заполнение свойств объекта.

  2. с использованием синтаксиса привязки данных (<%# %>), безусловно, может использоваться для заполнения в свойствах управления, но вам нужно обернуть элемент управления в привязке данных контейнер (как повторитель) и вызов DataBind (), чтобы получить Произойдет замена.

1 голос
/ 14 ноября 2013

Я знаю, что это старый, но я нашел эту тему в Google довольно быстро, поэтому я просто наберу это.

Я только что заметил, когда помогал коллеге, что вы можете сделать это с помощью UserControls в foreach. Обратите внимание, что я проверил это только на его примере.

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

Если это неприменимо для вас, по крайней мере, для других.

0 голосов
/ 30 октября 2009

Хотя ответ Джастина Гранта , вероятно, сработал бы просто отлично, мы решили просто загрузить пользовательский элемент управления и вызвать метод DisplayResults.

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

Это не полный код, но это то, что было необходимо для решения проблемы, которую я рассмотрел в этом вопросе. Загружая пользовательский элемент управления таким образом, мы можем установить нужные нам свойства и отобразить элемент управления uesr с правильной информацией.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...