views:

2916

answers:

6

I have a repeater control with a check box, if I check the box then my delete functionality will delete an item in the underlying table.

When I test the delete functionality on an aspx page with a code behind page, everything works fine. Hooray!

However, when I take the repeater and put it into a User Control, the delete functionality thinks that my repeater control has no items.

Code as below, I've tried to strip out the unnecessary code. I asked this question on the asp.net forums but no-one responded!

asxc:

<%@ Control  AutoEventWireup="true" Inherits="Moto.Web.UI.UserControls.Messages.MessageListForm" Language="C#" %>

<asp:button id="btnDelete" runat="server" text="Delete" OnClick="btnDelete_Click" ></asp:button>

<asp:Repeater ID="RepeaterMessageList"  runat="server" EnableViewState="true" >
    <ItemTemplate >
        <div class="messageContainer item" >
            <div class="messageListLeft">
                <div class="messageList">  
                    <asp:Image ID="imgUser" runat="server" CssClass="" />
                    <asp:CheckBox ID="chkDeleteMe" runat="server" Text="test" />
                </div>
            </div>
        </div>
    </ItemTemplate>

</asp:Repeater>

Code file:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections;
using System.Collections.Generic;
using System.IO;

namespace Moto.Web.UI.UserControls.Messages
{
    public class MessageListForm : Moto.Web.UI.UserControls.UserControl//System.Web.UI.UserControl
    {
        private string userGUID;
        private MembershipUser MembershipUser;
        private Moto.Business.UserComponent userComponent;
        private Moto.Business.User user;
        private Button cmdPrev;
        private Button cmdNext;
        private Button cmdNewest;
        private Button cmdOldest;
        private Label lblCurrentPage;
        private Label lblMessage;
        private HyperLink hypPageRedirect;
        private Repeater RepeaterMessageList;
        private MessageView DisplayMessages = MessageView.Inbox;//default setting

        private Button btnDelete;
        private Label lblConfirmDelete;
        protected Button btnConfirmDelete;
        protected Button btnCancelDelete;

        enum MessageView
        {
            Inbox,  //0
            Sent    //1
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            this.InitializePage();
        }

        protected void InitializePage()
        {
            this.cmdNext = (Button)FindControl("cmdNext");
            this.cmdPrev = (Button)FindControl("cmdPrev");
            this.cmdOldest = (Button)FindControl("cmdOldest");
            this.cmdNewest = (Button)FindControl("cmdNewest");
            this.lblCurrentPage = (Label)FindControl("lblCurrentPage");
 //           this.RepeaterMessageList = (Repeater)FindControl("RepeaterMessageList");

            this.RepeaterMessageList = (Repeater)FindControlRecursive(this, "RepeaterMessageList");


            this.hypPageRedirect = (HyperLink)FindControl("hypPageRedirect");
            this.lblMessage = (Label)FindControl("lblMessage");
            //delete functionality
            this.btnDelete = (Button)FindControl("btnDelete");
            this.lblConfirmDelete = (Label)FindControl("lblConfirmDelete");
            this.btnConfirmDelete = (Button)FindControl("btnConfirmDelete");
            this.btnCancelDelete = (Button)FindControl("btnCancelDelete");

            //where are we coming from - are we the Logged in user or just a voyeur?
            if (Page.User.Identity.IsAuthenticated)
            {
                this.userComponent = new Moto.Business.UserComponent();

                this.MembershipUser = Membership.GetUser();//user logged in
                this.userGUID = this.MembershipUser.ProviderUserKey.ToString();//signed in user
                this.user = this.userComponent.GetByUserGUID(this.userGUID);
            }
            else
            {
                Response.Redirect("~/default.aspx");
            }

            if (null != this.Page.Request.QueryString["viewing"])
            {
                //reset the enum value
                DisplayMessages = this.Page.Request.QueryString["viewing"].ToLower() == "sent" ? MessageView.Sent : MessageView.Inbox;
                CurrentPage = 0;//if it's a redirect then reset the Current Page
            }
        }

        void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                ItemsGet();//on post back we'll call it elsewhere
            }

            switch (DisplayMessages)
            {
                case MessageView.Sent:
                    this.hypPageRedirect.Text += "Inbox";
                    this.hypPageRedirect.NavigateUrl += "?viewing=Inbox";
                    break;
                case MessageView.Inbox:
                    this.hypPageRedirect.Text += "Sent Items";
                    this.hypPageRedirect.NavigateUrl += "?viewing=Sent";
                    break;

            }
        }

        protected void cmdPrev_Click(object sender, EventArgs e)
        {
            // Set viewstate variable to the previous page
            CurrentPage -= 1;

            // Reload control
            ItemsGet();
        }

        protected void cmdNext_Click(object sender, EventArgs e)
        {
            // Set viewstate variable to the next page
            CurrentPage += 1;

            // Reload control
            ItemsGet();
        }

        protected void cmdNewest_Click(object sender, EventArgs e)
        {
            // Set viewstate variable to the previous page
            CurrentPage = 0;

            // Reload control
            ItemsGet();
        }

        protected void cmdOldest_Click(object sender, EventArgs e)
        {
        }

        public void RepeaterMessageList_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {

            // Execute the following logic for Items and Alternating Items.
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {

                //Are we vieing the Inbox or Sent items?
                if (DisplayMessages == MessageView.Inbox)
                {
                    .........Do stuff
                }
                else
                {
                    .........Do stuff
                }
            }
        }

        private void ItemsGet()
        {
//            this.RepeaterMessageList = (Repeater)FindControl("RepeaterMessageList");
            this.RepeaterMessageList.ItemDataBound += new RepeaterItemEventHandler(RepeaterMessageList_ItemDataBound);


            // Populate the repeater control with the Items DataSet
            PagedDataSource objPds = new PagedDataSource();

            if (DisplayMessages == MessageView.Inbox)//which table are we getting data from?
            {
                List<Moto.Business.MessageReceived> messages;
                Moto.Business.MessageReceivedComponent messageComponent =
                    new Moto.Business.MessageReceivedComponent();
                messages = messageComponent.GetByReceiverGUID(this.user.UserGUID);

                objPds.DataSource = messages;
            }
            else
            {
                List<Moto.Business.MessageSent> messages;
                Moto.Business.MessageSentComponent messageComponent =
                    new Moto.Business.MessageSentComponent();
                messages = messageComponent.GetBySenderGUID(this.user.UserGUID);

                objPds.DataSource = messages; //Items.Tables[0].DefaultView;
            }


            // Indicate that the data should be paged
            objPds.AllowPaging = true;

            // Set the number of items you wish to display per page
            objPds.PageSize = 25;

            // Set the PagedDataSource's current page
            objPds.CurrentPageIndex = CurrentPage;

            this.lblCurrentPage.Text = "Page " + (CurrentPage + 1).ToString() + " of "
                + objPds.PageCount.ToString();

            // Disable Prev or Next buttons if necessary
            this.cmdPrev.Enabled = !objPds.IsFirstPage;
            this.cmdNext.Enabled = !objPds.IsLastPage;
            this.cmdOldest.Enabled = !objPds.IsLastPage;
            this.cmdNewest.Enabled = !objPds.IsFirstPage;

            this.RepeaterMessageList.DataSource = objPds;
            this.RepeaterMessageList.DataBind();
        }

        public int CurrentPage
        {
            get
            {
                // look for current page in ViewState
                object o = this.ViewState["_messagesCurrentPage"];
                if (o == null)
                    return 0; // default page index of 0
                else
                    return (int)o;
            }

            set
            {
                this.ViewState["_messagesCurrentPage"] = value;
            }
        }
        protected void btnDelete_Click(object sender, EventArgs e)
        {

            foreach (RepeaterItem item in this.RepeaterMessageList.Items)
            {
                CheckBox chkDeleteMe = item.FindControl("chkDeleteMe") as CheckBox;
                TextBox test = item.FindControl("test") as TextBox;
                if (chkDeleteMe.Checked)
                {
                    if (DisplayMessages == MessageView.Inbox)//which table are we getting data from?
                    {
                    .........Do stuff

                    }
                    else
                    {
                    .........Do stuff

                    }
                }
            }          
            // Reload control
            ItemsGet();
        }

        protected Control FindControlRecursive(Control root, string id)
        {
            if (root.ID == id)
            {
                return root;
            }

            foreach (Control c in root.Controls)
            {
                Control t = FindControlRecursive(c, id);
                if (t != null)
                {
                    return t;
                }
            }
            return null;
        }

}

Any help greatly appreciated!

A: 

So it binds to the repeater and displays all the items correctly but when repeating through the list of items on postback nothing is found?

Is the delete event definately being fired? What is visible after you have hit the delete button? (e.g. is the table empty or does it still display all the items)

Update:

Comment out the GetItems method and see if the table is empty or not on postback. It sounds like your repeaters viewstate isn't populating the control again or something.

John_
A: 

The Delete event fires but in the fornext...loop the repeater thinks it has no items.

After looping it then calls the ItemsGet() Method which returns all data from the table.

A: 

How is the usercontrol loaded? does the page have viewstate enabled?

AndreasN
A: 

Try to move the InitializePage() method to another place. I don´t know why, but I had the same problem and the problem was when I try to access some controls in the OnInit event. I moved to event OnPreLoad() and works.

I hope to help you...

+1  A: 

I think the problem is that when the delete button is clicked the Page_Load is fired again and since its a postback it does not execute the ItemsGet method and hence the repeater does not have the data.

Try putting the ItemsGet method call in the OnPreRender event instead of Page_Load.

Jomit

Jomit
A: 

Hey Jomit,

The PreRender solution also worked in our case, where we had such code in two pages of our application. This was working perfect in .Net 1.1 but however broke when we ported this code to .Net 2.0.

Not sure why it broke without any major changes to codebase.

Thanks for the OnPreRender tip!

-Ghanshyam