Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding value to list stored in session and then using as datasource for repeater

I have two repeaters on my page. The first repeater has a LinkButton in it, with a commandname and commandarguement. When the linkbutton is clicked the value of commandarguement is supposed to be stored in a Session containing List. Then I use the value of Session List to bind the second repeater.

I am having two problems:

1) I am binding the second repeater in the OnInit event. The event handler that is executed when the LinkButton in the first repeater is executed AFTER the init event - therefore when data binding takes place the new value has not been added to the session yet. I can't bind the data any later than the init event because the controls within the second repeater need to be maintained using viewstate (or other).

2) In the second repeater there are two dropdownlists. Both are databound in the repeaters itemdatabound event. When the first DDL is changed, I need to filter the values in the second DDL. But this just isnt happening.

For the purposes of a clearer example, I have stripped the code out of my application and created a very simple aspx page - all of the code is below. Thanks to Bobby who has already helped with this.

Really hope someone can help as I am stumped!

Markup:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Repeater-Viewstate.aspx.cs" Inherits="test_Repeater_Viewstate" ViewStateMode="Enabled" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>Repeater Test</h1>
        <h2>Repeater 1</h2>
        <asp:Repeater runat="server" Visible="true" ID="rptListItems">
            <ItemTemplate>
                Image ID: <asp:Literal ID="ImageID" runat="server" />&nbsp;&nbsp;
                <asp:LinkButton runat="server" CommandName="SelectImage" Text="Add to list" ID="AddToListCommand" />
                <hr />
            </ItemTemplate>
        </asp:Repeater>
        <h2>Repeater 2</h2>
        <asp:Repeater runat="server" Visible="true" ID="rptSelectedItems" ViewStateMode="Enabled">
            <ItemTemplate>
                The value of the item you selected is: <asp:TextBox runat="server" ID="ImageIDInput"/>
                <asp:DropDownList runat="server" ID="OptionsInput" AppendDataBoundItems="true" AutoPostBack="true" >
                    <asp:ListItem Text="Please choose..." Value="0" />
                </asp:DropDownList>
                <asp:DropDownList runat="server" ID="AttributesInput" runat="server" AppendDataBoundItems="true">
                    <asp:ListItem Text="Please choose..." Value="0" />
                </asp:DropDownList>
                <hr style="clear: both;" />
            </ItemTemplate>
        </asp:Repeater>
        <asp:Button runat="server" Text="Postback" />
    </div>
    </form>
</body>
</html>

Code behind:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class test_Repeater_Viewstate : System.Web.UI.Page
{

    //DUMMY Data for 1st Repeater
    public class MyRepeaterDataSource {

        public int ID { get; set; }
        public string Title { get; set; }

    }

    private List<MyRepeaterDataSource> _items;
    public List<MyRepeaterDataSource> Items {
        get {
            if (_items == null)
                _items = new List<MyRepeaterDataSource>();
            return _items;
        }
        set {
            _items = value;
        }
    }

    //END dummy data

    //DUMMY data for 1st dropdownlist in second repeater
    public class FirstDDLClass {

        public int ID { get; set; }
        public string Title { get; set; }

    }

    private List<FirstDDLClass> _firstDDLItems;
    public List<FirstDDLClass> FirstDDLItems {
        get {
            if (_firstDDLItems == null)
                _firstDDLItems = new List<FirstDDLClass>();
            return _firstDDLItems;
        }
        set {
            _firstDDLItems = value;
        }
    }

    //DUMMY data for 2nd dropdownlist in second repeater
    public class SecondDDLClass {

        public int ID { get; set; }
        public int ForeignKey { get; set; }
        public string Title { get; set; }
    }

    private List<SecondDDLClass> _secondDDLItems;
    public List<SecondDDLClass> SecondDDLItems {
        get {
            if (_secondDDLItems == null)
                _secondDDLItems = new List<SecondDDLClass>();
            return _secondDDLItems;
        }
        set {
            _secondDDLItems = value;
        }
    }

    public List<string> SelectedItems {
        get {
            if (Session["SelectedItems"] == null)
                Session["SelectedItems"] = new List<string>();
            return (List<string>)(Session["SelectedItems"]);
        }
        set {
            Session["SelectedItems"] = value;
        }
    }


    protected override void OnInit(EventArgs e) {


        //register events
        this.rptListItems.ItemDataBound += new RepeaterItemEventHandler(rptListItems_ItemDataBound);
        this.rptListItems.ItemCommand += new RepeaterCommandEventHandler(rptListItems_ItemCommand);
        this.rptSelectedItems.ItemDataBound += new RepeaterItemEventHandler(rptSelectedItems_ItemDataBound);

        //create a dummy list to populate first repeater
        MyRepeaterDataSource dataSource1 = new MyRepeaterDataSource();
        dataSource1.ID = 1;
        dataSource1.Title = "Item 1";
        Items.Add(dataSource1);

        MyRepeaterDataSource dataSource2 = new MyRepeaterDataSource();
        dataSource2.ID = 2;
        dataSource2.Title = "Item 2";
        Items.Add(dataSource2);

        MyRepeaterDataSource dataSource3 = new MyRepeaterDataSource();
        dataSource3.ID = 3;
        dataSource3.Title = "Item 3";
        Items.Add(dataSource3);

        MyRepeaterDataSource dataSource4 = new MyRepeaterDataSource();
        dataSource4.ID = 4;
        dataSource4.Title = "Item 4";
        Items.Add(dataSource4);

        //create a dummy list to populate the first dropdownlist in the second repeater
        FirstDDLClass class1 = new FirstDDLClass();
        class1.ID = 1;
        class1.Title = "Option 1";
        FirstDDLItems.Add(class1);

        FirstDDLClass class2 = new FirstDDLClass();
        class2.ID = 2;
        class2.Title = "Option 2";
        FirstDDLItems.Add(class2);

        //create a dummy list to populate the second dropdownlist in the second repeater
        SecondDDLClass class3 = new SecondDDLClass();
        class3.ID = 1;
        class3.ForeignKey = 1;
        class3.Title = "Attribute 1";
        SecondDDLItems.Add(class3);

        SecondDDLClass class4 = new SecondDDLClass();
        class4.ID = 1;
        class4.ForeignKey = 1;
        class4.Title = "Attribute 2";
        SecondDDLItems.Add(class4);

        SecondDDLClass class5 = new SecondDDLClass();
        class5.ID = 1;
        class5.ForeignKey = 2;
        class5.Title = "Attribute 3";
        SecondDDLItems.Add(class5);


        if (!this.Page.IsPostBack) {

            //bind 1st repeater
            this.rptListItems.DataSource = Items;
            this.rptListItems.DataBind();

        }

        //bind second repeater
        this.rptSelectedItems.DataSource = SelectedItems;
        this.rptSelectedItems.DataBind();


        base.OnInit(e);
    }

    protected void Page_Load(object sender, EventArgs e)
    {



    }

    void rptListItems_ItemDataBound(object sender, RepeaterItemEventArgs e) {

        Literal imageIDLiteral = e.Item.FindControl("ImageID") as Literal;
        if (imageIDLiteral is Literal) {

            imageIDLiteral.Text = DataBinder.Eval(e.Item.DataItem, "ID").ToString();

        }

        LinkButton linkButton = e.Item.FindControl("AddToListCommand") as LinkButton;
        if (linkButton is LinkButton) {

            linkButton.CommandArgument = DataBinder.Eval(e.Item.DataItem, "ID").ToString();

        }

    }


    void rptListItems_ItemCommand(object source, RepeaterCommandEventArgs e) {

        switch (e.CommandName) {

            case "SelectImage":

                this.SelectedItems.Add(e.CommandArgument.ToString());

                break;

        }

    }

    void rptSelectedItems_ItemDataBound(object sender, RepeaterItemEventArgs e) {

        switch (e.Item.ItemType) {

            case ListItemType.AlternatingItem:
            case ListItemType.Item:

                TextBox textBox = e.Item.FindControl("ImageIDInput") as TextBox;
                if (textBox is TextBox) {

                    textBox.Text = e.Item.DataItem.ToString();

                }

                DropDownList ddl1 = e.Item.FindControl("OptionsInput") as DropDownList;
                if (ddl1 is DropDownList) {

                    ddl1.DataValueField = "ID";
                    ddl1.DataTextField = "Title";
                    ddl1.DataSource = this.FirstDDLItems;
                    ddl1.DataBind();

                }

                DropDownList ddl2 = e.Item.FindControl("AttributesInput") as DropDownList;
                if (ddl2 is DropDownList) {

                    ddl2.DataValueField = "ID";
                    ddl2.DataTextField = "Title";
                    if (ddl1.SelectedIndex != 0) {
                        ddl2.DataSource = this.SecondDDLItems.Where(f => f.ForeignKey == Convert.ToInt32(ddl1.SelectedValue));
                        ddl2.DataBind();
                    }

                }




                break;

        }

    }

}

Thanks in advance guys

Al

like image 861
higgsy Avatar asked Sep 22 '11 13:09

higgsy


1 Answers

If you add the following code:

    protected void OptionsInput_SelectedIndexChanged(object sender, EventArgs e)
    {
        DropDownList optionsInput = sender as DropDownList;
        DropDownList ddl2 = optionsInput.Parent.FindControl("AttributesInput") as DropDownList;
        if (ddl2 is DropDownList)
        {

            ddl2.DataValueField = "ID";
            ddl2.DataTextField = "Title";
            if (optionsInput.SelectedIndex != 0)
            {
                ddl2.DataSource = this.SecondDDLItems.Where(f => f.ForeignKey == Convert.ToInt32(optionsInput.SelectedValue));
                ddl2.DataBind();
            }

        }
    }

And the following markup:

<asp:DropDownList runat="server" ID="OptionsInput" AppendDataBoundItems="true" AutoPostBack="true" OnSelectedIndexChanged="OptionsInput_SelectedIndexChanged" >

(Specifically, adding the OnSelectedIndexChanged="OptionsInput_SelectedIndexChanged")

It worked for me.

like image 160
MarkMcDowell Avatar answered Nov 11 '22 14:11

MarkMcDowell