2009-01-30 9 views
1

La situation est la suivante:Quelle est la meilleure façon de montrer plusieurs cases à cocher pour plusieurs enregistrements dans ASP.NET

J'ai une base de données avec beaucoup de RSS Catégories, qui à leur tour ont beaucoup de fils RSS. Je veux les afficher de la manière suivante:

RSS Category 1 
[ ] Rss Feed 1 
[ ] Rss Feed 2 
[ ] Rss Feed 3 

RSS Category 2 
[ ] Rss Feed 1 
[ ] Rss Feed 2 
[ ] Rss Feed 3 

Où [] représente une case à cocher.

Chaque flux RSS est donc retiré de la base de données en fonction de l'identifiant de la catégorie RSS parent. Je ne peux pas utiliser CheckBoxList car chaque case à cocher doit être contenue dans un élément de liste non ordonné. J'ai besoin que le balisage soit sémantiquement correct et je ne peux pas utiliser les adaptateurs de contrôle.

J'ai initialement imaginé deux répéteurs imbriqués, l'extérieur vers une liste de catégories RSS de la base de données qui affiche l'en-tête Catégorie et contient un contrôle caché avec l'ID de catégorie, puis un répéteur interne avec les flux RSS pour cette catégorie .

Comment puis-je accéder à l'identifiant de catégorie à partir du contrôle de champ caché dans le répéteur parent afin que je puisse rechercher les flux RSS corrects?

Répondre

0

Si vous ne pouvez pas utiliser CheckBoxList, vous devrez gérer les valeurs manuellement.

Vous pouvez manuellement .Controls.Add (nouveau LiteralControl ("</li li > < >")) entre eux, mais c'est un peu sur le côté collant.

Vous pouvez utiliser un DataGrid avec un TemplateColumn pour vous y frayer un chemin, mais ce n'est pas élégant.

Pourquoi cela doit-il figurer dans une liste? Le CheckBoxList ne fournit-il pas la fonctionnalité dont vous avez besoin?

Également, essayez myCheckBox.Parent.Controls.FindControl ("MyHiddenField"). Valeur.

Comment puis-je accéder à l'identifiant de catégorie à partir du contrôle de champ caché dans le répéteur parent afin que je puisse rechercher les flux RSS corrects?

0

J'ai une application où je dois créer dynamiquement une variété de contrôles différents. Cela fonctionne bien pour plusieurs cases à cocher (ou n'importe quoi d'autre d'ailleurs).

Tout d'abord, sur votre page ASPX, placez le contrôle "PlaceHolder":

<asp:PlaceHolder runat="server" id="CtrlCanvas" /> 

Maintenant, dans votre code derrière, créez vos commandes dynamiquement:

Label aLbl = new Label {Text = "Prompt: ", ID = ("WSLabel" + counter++)}; 
CtrlCanvas.Controls.Add(aLbl); 

C'était une étiquette, ici est une zone de texte:

TextBox aBox = new TextBox {ID = "XTest1", Columns = 5, Text = " ", Width = 50}; 
CtrlCanvas.Controls.Add(aBox); 
aBox.Focus(); 

Voici une liste de boîte de radio:

RadioButtonList WRRadio = new RadioButtonList { ID = "XTestRadioList1" }; 
WRRadio.Items.Add("Walking &nbsp; "); 
WRRadio.Items.Add("Running"); 
WRRadio.SelectedIndex = WalkRun; 
WRRadio.RepeatColumns = 2; 
CtrlCanvas.Controls.Add(WRRadio); 

C'est tout ce qu'il y a à créer le contrôle. Pour obtenir les valeurs, vous devez avoir une convention de nommage qui vous permet d'identifier le préfixe qu'ASP.NET met sur vos contrôles. J'utilise "XTest".Voici un exemple:

foreach (string aStr in Form.AllKeys) 
{ 
    int position = aStr.IndexOf("XTest"); // XTest is used in my controls 
    if (position > 0) 
    { 
     // Get the *prefix* added by ASP.NET 
     CtlPrefix = aStr.Substring(0, position); 
     break; 
    } 
} 

Maintenant, pour obtenir la valeur stockée dans un contrôle spécifique, il est facile:

string result = Form.Get(CtlPrefix + "XTest1") 

Pour les boîtes de radio, au moins, la retourne le index sélectionné. J'imagine que vous nommerez chaque case à cocher séparément de sorte que vous pouvez simplement vérifier 0 ou 1.

Espérons que cela aide!

0

J'ai besoin du balisage pour être sémantiquement correct et je ne peux pas utiliser les adaptateurs de contrôle.

Faites-vous référence à these adapters? Si non, vous devriez jeter un coup d'oeil. Vous n'avez pas besoin d'utiliser l'ensemble entier; Modifiez votre fichier .browser pour spécifier uniquement le CheckBoxListAdapter. Cela devrait faire exactement ce dont vous avez besoin. De cette façon, vous pouvez simplement prendre un contrôle Repeater ou ListView et le classer dans la liste des catégories, puis y ajouter un CheckBoxList.

2

Je pense que vous cherchez peut-être quelque chose comme ceci:

ASPX:

<asp:Repeater ID="rptOuter" runat="server" OnItemDataBound="rptOuter_ItemDataBound"> 
     <HeaderTemplate> 
      <ul style="list-style-type: none"> 
     </HeaderTemplate> 
     <ItemTemplate> 
      <li id='<%# Eval("Id") %>'> 
      <%# Eval("Category") %> 
      <asp:Repeater ID="rptInner" runat="server"> 
       <HeaderTemplate> 
        <ul style="list-style-type: none"> 
       </HeaderTemplate> 
       <ItemTemplate> 
        <li> 
         <asp:CheckBox ID="chkFeed" runat="server" Text='<%# Eval("Feed") %>' /> 
        </li> 
       </ItemTemplate> 
       <FooterTemplate> 
        </ul> 
       </FooterTemplate> 
      </asp:Repeater> 
      </li> 
     </ItemTemplate> 
     <FooterTemplate> 
      </ul> 
     </FooterTemplate> 
</asp:Repeater> 

code Derrière:

protected void Page_Load(object sender, EventArgs e) 
{ 
    using (SqlConnection conn = new SqlConnection(connString)) 
    { 
     conn.Open(); 
     SqlCommand cmd = new SqlCommand("SELECT id, category FROM rsscategory_tbl", conn); 
     SqlDataReader rdr = cmd.ExecuteReader(); 
     this.rptOuter.DataSource = rdr; 
     this.rptOuter.DataBind(); 
     rdr.Close(); 
    } 
} 

protected void rptOuter_ItemDataBound(object sender, RepeaterItemEventArgs e) 
{ 
    if (e.Item.ItemType == ListItemType.Item || 
     e.Item.ItemType == ListItemType.AlternatingItem) 
    {    
     using (SqlConnection conn = new SqlConnection(connString)) 
     { 
      conn.Open(); 
      System.Data.Common.DbDataRecord rd = (System.Data.Common.DbDataRecord)e.Item.DataItem; 
      SqlCommand cmd = new SqlCommand("SELECT feed FROM rssfeed_tbl WHERE categoryid = " + rd.GetInt32(rd.GetOrdinal("id")), conn); 
      Repeater rptInner = (Repeater)e.Item.FindControl("rptInner"); 
      SqlDataReader rdr = cmd.ExecuteReader(); 
      rptInner.DataSource = rdr; 
      rptInner.DataBind(); 
      rdr.Close(); 
     } 
    } 
} 
Questions connexes