views:

1061

answers:

4

The situation is as follows:

I have a database with many RSS Categories, that in turn have many RSS Feeds. I want to display them in the following fashion:

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

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

Where [ ] represents a checkbox.

So each RSS Feed is pulled out of the database depending on the id of the parent RSS category. I cannot use CheckBoxList as each checkbox must be contained inside an unordered list list item. I need the markup to be semantically correct and cant use the Control Adapters.

I initially imagined two nested repeaters, the outside one databound to a list of RSS Categories from the database which displays the Category header and contains a hidden control with the Category ID, then an inner Repeater with the RSS Feeds for that category.

How do I access the Category id from the hidden field control in the parent repeater so I can look up the correct RSS Feeds?

A: 

If you can't use a CheckBoxList, you'll have to handle the values manually.

You can manually .Controls.Add(new LiteralControl("</li><li>")) between them, but that's a bit on the tacky side.

You could use a DataGrid with a TemplateColumn to hack your way into it, but that's not elegant.

Why does this need to be in a list? Doesn't the CheckBoxList provide the functionality you require?

Also, try myCheckBox.Parent.Controls.FindControl("MyHiddenField").Value .

How do I access the Category id from the hidden field control in the parent repeater so I can look up the correct RSS Feeds?

tsilb
A: 

I have an application where I need to dynamically create a whole variety of different controls. It works fine for multiple checkboxes (or anything else for that matter).

First, on your ASPX page, place the "PlaceHolder" control:

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

Now, in your code behind, create your controls dynamically:

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

That was a label, here is a TextBox:

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

Here is a radio box list:

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);

That is all there is to creating the control. To get the values, you'll need to have a naming convention that allows you to identify the prefix that ASP.NET puts on your controls. I use "XTest". Here is an example:

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;
    }
 }

Now to get the value stored in a specific control it is easy:

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

For radio boxes, at least, the Get returns the selected index. I imagine that you'll name each check box separately so you can just check for 0 or 1.

Hope this helps!

Mark Brittingham
A: 

I need the markup to be semantically correct and cant use the Control Adapters.

Are you referring to these adapters? If not, you should take a look. You don't have to use the entire set; Edit your .browser file to specify only the CheckBoxListAdapter. It should do exactly what you need. This way you can simply take a Repeater or ListView control and databind it to the list of categories, then put a CheckBoxList inside that.

Brant Bobby
+2  A: 

I think you might be looking for something like this:

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 Behind:

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();
        }
     }
}
Phaedrus