2009-10-29 7 views
5

J'ai un contrôle utilisateur que j'utilise sur plusieurs pages pour afficher des informations sur un objet. Chaque fois que j'ai besoin d'utiliser ce contrôle, j'appelle une méthode appelée Display (sur la commande usercontrol) et transmets certaines valeurs.Définition des propriétés d'un contrôle utilisateur dans une boucle foreach

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

Cela fonctionne très bien, mais maintenant je dois utiliser cette commande dans une boucle foreach dans une page ASPX.

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

L'objet catégories possède les méthodes et propriétés que je transmettrais dans la méthode Display. Alors, comment pourrais-je définir correctement les valeurs?

J'ai essayé de faire les propriétés sur le public de contrôle de l'utilisateur et les mettre juste la façon suivante:

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

Cela ne fonctionne pas, parce que les propriétés s'envoyés sont vides. Si j'utilise <% = alors ça ne marche pas et en fait jette une erreur car il ne reconnaît pas 'c' (à moins que je ne supprime runat = "server" alors il compilera au moins, ça ne marchera pas quand même .

Quelle est la bonne façon de le faire

Edit:?. en outre, un contrôle répéteur pourrait rendre cela plus facile pour databinding, mais je préfère éviter l'utilisation de tout contrôle .NET

Répondre

0

Alors que Justin Grant's answer aurait probablement hav fonctionnait très bien, nous avons décidé d'aller avec le chargement de tout le contrôle de l'utilisateur et appelant la méthode DisplayResults.

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

Ce n'est pas le code complet, mais c'est ce qui était nécessaire pour résoudre le problème que j'ai traité dans la question. En chargeant le contrôle utilisateur de cette façon, nous pourrions définir les propriétés dont nous avions besoin et afficher le contrôle uesr avec les informations correctes.

10

Dans une page WebForms, la façon dont cela est généralement géré à l'aide de DataBinding Au lieu d'une boucle foreach, vous pouvez utiliser un contrôle Repeater, définir sa propriété DataSource sur <%#Categories%>, puis utiliser la syntaxe de liaison de données dans votre latte r exemple ci-dessus, sauf au lieu de c, vous devrez lancer Container.DataItem au type approprié dans votre contrôle. Comme ceci:

<%@ 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> 

La seule réserve est que vous devrez appeler la méthode DataBind() du répéteur somwhere, généralement dans la méthode Page_Load. Personnellement, j'ai toujours trouvé que la liaison de données était douloureuse - la conversion et le besoin d'appeler des données liées me semblent beaucoup moins naturels que la méthode foreach que vous avez essayée ci-dessus. C'est probablement la chose que j'aime le plus à propos de ASP.NET MVC - vos vues MVC peuvent beaucoup plus facilement utiliser le modèle d'itération foreach qui est beaucoup plus simple, à mon humble avis. Cela dit, si vous devez vous en tenir à WebForms, la liaison de données avec casting est le chemin de moindre résistance.

BTW, vos approches ci-dessus n'a pas fonctionné parce que:

  1. runat = propriétés de contrôle ASP.NET serveur ne peuvent pas être remplis à l'aide <%= %> syntax-- qui est seulement utile pour la sortie en texte brut, non pour en remplissant les propriétés de l'objet.

  2. en utilisant la syntaxe de liaison de données (<%# %>) peut certainement être utilisé pour remplir dans les propriétés de contrôle, mais vous devez pour envelopper le contrôle dans un conteneur de liaison de données (comme un répéteur) et appelez DataBind() afin d'obtenir le remplacement .

+1

Un répéteur serait probablement le bon moyen, mais nous essayons d'éviter l'utilisation de contrôles. NET autant que possible et préfèrent aller à la génération de HTML. – Brandon

+0

Oui, moi aussi ... Je trouve aussi l'approche en boucle et émission HTML beaucoup plus simple. C'est pourquoi j'aime ASP.NET MVC. Mais avec Web Forms, si vous utilisez déjà vos propres contrôles personnalisés et devez remplir leurs propriétés, en particulier en boucle, l'utilisation de la liaison de données est la solution la plus simple. Par curiosité, pourquoi éviter les contrôles intégrés d'asp.net? Est-ce une préoccupation liée à la performance ou quelque chose d'autre? Le contrôle du répéteur est * très * bare-bones et fast-- et ne provoque aucun viewstate ou autre crud comme ça. Le répéteur peut agir comme une boucle foreach masquerading comme un contrôle. –

+0

C'est plus une question de cohérence/performance. À l'origine, mon patron avait abandonné les contrôles .NET dans le projet parce que les contrôles/AjaxToolKit étaient trop lourds pour ce dont nous avions besoin, donc une approche purement HTML/jQuery a été adoptée. Si tout le reste échoue je pourrais jeter dans un seul répéteur, je me demandais juste s'il y avait un moyen de le faire en utilisant le chemin que nous avons déjà commencé. – Brandon

1

Je sais que c'est vieux, mais j'ai trouvé ce fil de discussion via google tout à fait instantané, donc je vais juste taper ceci.

Je viens de remarquer en aidant un collègue que vous pourriez faire comme ça avec UserControls foreach. Notez que je l'ai seulement testé à travers son exemple.

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

Si cela ne vous concerne pas, il pourrait être pour d'autres.

+1

Vous devez définir la propriété avant d'appeler le contrôle. Mais sinon, pratique si c'est un cas simple d'une seule instance d'un contrôle utilisé dans une boucle. – Reuben

Questions connexes