Wrox Programmer Forums

Need to download code?

View our list of code downloads.

Go Back   Wrox Programmer Forums > ASP.NET and ASP > ASP.NET 3.5 > ASP.NET 3.5 Basics
Password Reminder
Register
Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read
ASP.NET 3.5 Basics If you are new to ASP or ASP.NET programming with version 3.5, this is the forum to begin asking questions. Please also see the Visual Web Developer 2008 forum.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the ASP.NET 3.5 Basics section of the Wrox Programmer to Programmer discussions. This is a community of tens of thousands of software programmers and website developers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining today you can post your own programming questions, respond to other developers’ questions, and eliminate the ads that are displayed to guests. Registration is fast, simple and absolutely free .
DRM-free e-books 300x50
 
 
Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old May 22nd, 2008, 03:48 AM
Authorized User
 
Join Date: Dec 2006
Location: , , .
Posts: 35
Thanks: 0
Thanked 0 Times in 0 Posts
Default What if I need control value before event is fired

Hi,

I've just started working on somebody else's code and I had to add a dropdown list to a page which loads content from the database.

The problem is the content is loaded before the dropdownlist's selectedIndexChanged event is fired so i resorted to an ugly hack from my background as a classic ASP dev.

public string selectedItem
{
get { return HttpContext.Current.Request.Form["ctl00$CenterContent$selItem"];}
}

Clearly an experienced ASP.NET dev will probably grimace at this! Is there a better way of achieving what I am trying to do?
__________________
http://www.thewebsiteshop.co.uk
  #2 (permalink)  
Old May 22nd, 2008, 04:16 AM
Imar's Avatar
Wrox Author
Points: 72,038, Level: 100
Points: 72,038, Level: 100 Points: 72,038, Level: 100 Points: 72,038, Level: 100
Activity: 100%
Activity: 100% Activity: 100% Activity: 100%
 
Join Date: Jun 2003
Location: Utrecht, Netherlands.
Posts: 17,080
Thanks: 80
Thanked 1,587 Times in 1,563 Posts
Default

It's difficult to tell without seeing the relevant code.

However, it sounds like you are rebinding your data on postback as well. Try wrapping the binding code in a Not PostBack block:

VB
If Not Page.IsPostBack Then
 ' data binding here
End If

C#
if (!Page.IsPostBack)
{
 // data binding here
}

Hope this helps,

Imar


---------------------------------------
Imar Spaanjaars
http://Imar.Spaanjaars.Com
Everyone is unique, except for me.
Author of Beginning ASP.NET 3.5 : in C# and VB, ASP.NET 2.0 Instant Results and Dreamweaver MX 2004
Want to be my colleague? Then check out this post.
  #3 (permalink)  
Old May 22nd, 2008, 04:54 AM
Authorized User
 
Join Date: Dec 2006
Location: , , .
Posts: 35
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Thanks Imar,

Adding !Page.IsPostBack just results in the list not being rendered after a postback.

There is a custom Page class at the top level which inherits from the System.Web.UI.Page base class.

The home page inherits the custom Page class and binds the data from it.

The custom Page class contains a property called PageVersionControl - a Custom WebControl class to which I've added my drop down list.

I added an EventHandler for the SelectedIndexChanged event of my list for which I have added a handler in the custom Page class but the problem seems to be that the Page class has obtained most of the data for the home page before the SelectedIndexChanged event has fired so it already has all the data for the page but from the previously selected item!

The only way I can see to get the selected item before the page obtains the data is to access the Form item but this seems to be frowned upon in .NET so I assume there is a better way of doing this but cannot figure it out :(

  code is pretty complex - I think it might just make things more confusing.

So are you saying

http://www.thewebsiteshop.co.uk
  #4 (permalink)  
Old May 22nd, 2008, 05:33 AM
Imar's Avatar
Wrox Author
Points: 72,038, Level: 100
Points: 72,038, Level: 100 Points: 72,038, Level: 100 Points: 72,038, Level: 100
Activity: 100%
Activity: 100% Activity: 100% Activity: 100%
 
Join Date: Jun 2003
Location: Utrecht, Netherlands.
Posts: 17,080
Thanks: 80
Thanked 1,587 Times in 1,563 Posts
Default

Quote:
quote:I think it might just make things more confusing
I doubt that's the case. It typically is the starting point of the fix.... (Provided you post the relevant code only; not a huge page without explanation).

Imar


---------------------------------------
Imar Spaanjaars
http://Imar.Spaanjaars.Com
Everyone is unique, except for me.
Author of Beginning ASP.NET 3.5 : in C# and VB, ASP.NET 2.0 Instant Results and Dreamweaver MX 2004
Want to be my colleague? Then check out this post.
  #5 (permalink)  
Old May 22nd, 2008, 06:43 AM
Authorized User
 
Join Date: Dec 2006
Location: , , .
Posts: 35
Thanks: 0
Thanked 0 Times in 0 Posts
Default

ok i've tried to cut the code down as much as i can.

home_page.aspx
Contains the PageVersionControl control

Code:
<%@ Page Language="C#" MasterPageFile="~/App_Layout/BabyArmy/SiteLayout.master" CodeFile="home_page.aspx.cs"
    Inherits="home_page" %>

<%@ Register TagPrefix="uc1" TagName="ContentListingGeneral" Src="UserControls/ContentListingGeneral.ascx" %>
<asp:Content ID="Content2" ContentPlaceHolderID="CenterContent" runat="Server">
    <div class="GenericBoxInternalPadded">
        <cms:PageVersionControl ID="PageVersionControl1" runat="server" CssClass="jump padded20"/>
    </div>
    <uc1:ContentListingGeneral ID="ContentListingGeneral" runat="server" Title="Articles" />
</asp:Content>
home_page.aspx.cs
Contains the code behind from above and binds the data to the ContentListingGeneral control

Code:
using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using CMS.Runtime;
using CMS.Runtime.Web.UI;

public partial class home_page : Page
{
    protected override void OnLoad(EventArgs e)
    {
        ContentListingGeneral.DataSource = CmsContext.Current.HierarchyItem.Pages;
        ContentListingGeneral.DataBind();
        base.OnLoad(e);
    }

}
PageVersionControl.cs
The PageVersionControl class
Code:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using AjaxControlToolkit;

namespace CMS.Runtime.Web.UI.WebControls
{
    /// <summary>
    /// Summary description for PageVersionControl
    /// </summary>
    public class PageVersionControl : WebControl
    {
        public event EventHandler SelectedHostChanged;

        public smnbss.CMS.Runtime.Web.UI.Page CMSPage
        {
            get
            {
                return this.Page as CMS.Runtime.Web.UI.Page;
            }
        }

        protected override void OnInit(EventArgs e)
        {
            if (this.CMSPage == null)
                throw new Exception("Cannot add PageVersionControl if Page Type != smnbss.CMS.Runtime.Web.UI.Page");
            if (this.CMSPage.VersionControl != null)
                throw new Exception("Cannot add more than one PageVersionControl per page");
            this.CMSPage.VersionControl = this;
            EnsureChildControls();
            base.OnInit(e);
        }

        private DropDownList hosts = new DropDownList();

        public PageVersionControl()
        {

        }

        public DropDownList HostSelector
        {
            get
            {
                return hosts;
            }
        }

        public string Host
        {
            get
            {
                if (!string.IsNullOrEmpty(hosts.SelectedValue))
                    return hosts.SelectedValue.ToString();
                else
                    return null;
            }
        }

        protected override void CreateChildControls()
        {
            hosts.SelectedIndexChanged += new EventHandler(hosts_SelectedIndexChanged);
            base.CreateChildControls();
            LoadHosts();
            Controls.Add(hosts);
        }

        void hosts_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (SelectedHostChanged != null)
                SelectedHostChanged(sender, e);
        }

        public void LoadHosts()
        {
            hosts.ID = "selHost";
            hosts.Items.Clear();
            hosts.Style.Add("float", "left");
            hosts.Style.Add("width", "175px");
            hosts.AutoPostBack = true;
            hosts.AppendDataBoundItems = true;
            hosts.DataTextField = "Name";
            hosts.DataValueField = "HostID";
            hosts.DataSource = CmsContext.Current.ModeIsUpdate ? CmsContext.Current.AllowedHosts : CmsContext.Current.Hosts;
            hosts.SelectedValue = CmsContext.Current.Host.HostID.ToString();
            hosts.DataBind();
        }
    }
}
Page.cs
The custom page class which contains the event handler for the dropdownlist.
Code:
using System;
using System.Collections;
using System.Web.UI;
using CMS.Runtime.Web.UI.WebControls;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace CMS.Runtime.Web.UI
{
    /// <summary>
    /// Summary description for Page.
    /// </summary>
    public class Page : System.Web.UI.Page
    {
        protected override void OnInit(EventArgs e)
        {
            if (VersionControl != null)
                VersionControl.SelectedHostChanged += HostSelector_SelectedIndexChanged;

            base.OnInit(e);
        }

        void HostSelector_SelectedIndexChanged(object sender, EventArgs e)
        {
            DropDownList list = (DropDownList)sender;
            CmsContext.Current.Host = HostInfoFactory.GetHostById(Convert.ToInt32(list.SelectedValue));

            CmsContext.Current.HierarchyItem.ClearCache();

            foreach (object wc in this._placeHolders)
            {
                ObjPlaceHolder owc = wc as smnbss.CMS.Runtime.Web.UI.WebControls.ObjPlaceHolder;
                if (owc != null && (owc.SupportVersion || owc.SupportLanguage))
                {
                    owc.InitializeData();
                    owc.BindData();
                    owc.ReloadUI();
                }
            }
        }

        protected override void OnPreInit(EventArgs e)
        {
            string pagename = this.Request.Url.Segments[this.Request.Url.Segments.Length -1 ];

            if (CmsContext.Current.Templates.Get(pagename) == null && this.AutoSaveTemplate)
            {
                TemplateTypeFactory.CreateNew(-1, pagename, pagename);
            }

            string layout = this.Layout;

            if (!string.IsNullOrEmpty(layout) && layout.ToLower() != "default")
            {
                this.MasterPageFile = this.MasterPageFile.Replace("App_Layouts/Default/", string.Format("App_Layouts/{0}/", layout));
            }

            if (!string.IsNullOrEmpty(this.Theme) && this.Theme != base.Theme)
            {
                base.Theme = this.Theme;
            }
            base.OnPreInit(e);
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
        }
    }
}
CMSContext.cs
The class which gets and sets the current Host and where I am capturing the form value
Code:
using System;
using System.Linq;
using System.Data.Linq;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using Microsoft.Practices.EnterpriseLibrary.Caching;
using CMS.Config;
using CMS.Runtime.Modules;
using System.Web.Profile;

namespace CMS.Runtime
{
    /// <summary>
    /// Summary description for CmsContext.
    /// </summary>
    public class CmsContext

        private static readonly object syncRoot = new Object();

        public static bool _initialized = false;
        private static volatile CmsContext instance;
        private static object sync = new object();

           private CmsContext()
        {
            _cacheManager = CacheFactory.GetCacheManager("CMSCache");
            try
            {
                _ApplicationConfiguration =
                    (ApplicationConfiguration) ConfigurationManager.GetSection("applicationConfiguration");
            }
            catch (Exception e)
            {
                throw new Cm****ception("Wrong Configuration", e);
            }
        }

        public static CmsContext Current
        {
            get
            {
                if (instance == null)
                {
                    lock (syncRoot)
                    {
                        if (instance == null)
                        {
                            instance = new CmsContext();
                        }
                    }
                }

                return instance;
            }
        }

        public HierarchyItem HierarchyItem
        {
            get
            {
                if (HttpContext.Current == null)
                    return null;
                return
                    GetItemValue<HierarchyItem>("CmsContext_HierarchyItem", null,
                                                delegate { return _hierarchyItemModule.Get(CurrentHierarchyItemID); });
            }
        }
 
        public HostCollection Hosts
        {
            get { return HostInfoFactory.GetHostInfo(string.Empty); }
        }

        public string AllowedHostID
        {
            get {
                if (HttpContext.Current == null)
                    return HostInfoFactory.GetDefaultAllowed(this.Hosts);
                return GetSessionValue<string>("AllowedHosts", HostInfoFactory.GetDefaultAllowed(this.Hosts), null); 
            }
            set { SetSessionValue<string>("AllowedHosts", value); }
        }


        public HostCollection AllowedHosts
        {
            get { return HostInfoFactory.GetHostInfo(this.AllowedHostID); }
        }

        public string selectedHostId
        {
            get { return HttpContext.Current.Request.Form["ctl00$CenterContent$selHost"]; }
        }

        public Host Host
        {
            get 
            {
                return GetItemValue<Host>("Host", null, delegate
                {
                    Host _host = null;
                    if (this.selectedHostId != null)
                    {
                        _host = HostInfoFactory.GetHostById(int.Parse(selectedHostId));
                    }
                    else
                    {
                        string requesturi = HttpContext.Current.Request.Url.Host;
                        if (HttpContext.Current.Request.Cookies["Host"] != null)
                        {
                            requesturi = HttpContext.Current.Request.Cookies["Host"].Value;
                        }

                        foreach (Host host in this.AllowedHosts)
                        {
                            if (host.HostUri == requesturi)
                            {
                                _host = host;
                                break;
                            }

                        }
                    }
                    if (_host == null) {
                        _host = HostInfoFactory.GetHostById(this.ModeIsUpdate ? this.AllowedHosts[0].HostID : this.Hosts[0].HostID);
                    }

                    return _host;
                });

            }
            set 
            {
                HttpCookie cookie = new HttpCookie("Host", value.HostUri);
                HttpContext.Current.Response.Cookies.Add(cookie);
                SetItemValue("Host", value);
            }
        }

        public V GetItemValue<V>(string propertyName, V nullValue, GetObjectDelegate<V> getobject)
        {
            if (HttpContext.Current == null || HttpContext.Current.Items[propertyName] == null)
            {
                if (getobject == null)
                    return default(V);

                V obj = getobject();
                if (obj != null)
                {
                    SetItemValue(propertyName, obj);
                    return obj;
                }
                else
                    return nullValue;
            }
            return (V) HttpContext.Current.Items[propertyName];
        }

        public void SetItemValue<V>(string propertyName, V value)
        {
            if (HttpContext.Current != null)
                HttpContext.Current.Items[propertyName] = value;
        }
    }
}
HierarchyItem.cs
The class which provides the data for the page
Code:
using System;
using System.Collections;
using System.Web;
using System.Data;
using CMS.Data;
using CMS.Runtime.Interfaces;
using System.Text.RegularExpressions;
using System.Collections.Generic;

namespace CMS
{
    /// <summary>
    /// Summary description for HierarchyItem.
    /// </summary>
    [Serializable]
    public class HierarchyItem : IDbObject
    { 
        public HierarchyItemCollection Pages
        {
            get
            {
                string objectId = string.Concat(Id, "_pages_", CmsContext.Current.Host.HostID.ToString());
                HierarchyItemCollection pages;
                if (LookUpObject(objectId) == null)
                {
                    pages = HierarchyItemFactory.GetHierarchyItemPages(Id);
                    CacheObject(objectId, pages);
                }
                else
                    pages = (HierarchyItemCollection)LookUpObject(objectId);

                return pages;
            }
        }
    }
}
So the issue again really is that the data is bound to the page before the SelectdIndexChanged event of the dropdownlist is fired and the only way I can see to get at the newly selected value is via the Form, but I get the impression this kind of code is a bit of a hack in .NET

Code:
HttpContext.Current.Request.Form["ctl00$CenterContent$selItem"]
Thanks again, Paul
  #6 (permalink)  
Old May 22nd, 2008, 07:30 AM
Imar's Avatar
Wrox Author
Points: 72,038, Level: 100
Points: 72,038, Level: 100 Points: 72,038, Level: 100 Points: 72,038, Level: 100
Activity: 100%
Activity: 100% Activity: 100% Activity: 100%
 
Join Date: Jun 2003
Location: Utrecht, Netherlands.
Posts: 17,080
Thanks: 80
Thanked 1,587 Times in 1,563 Posts
Default

Quote:
quote:(Provided you post the relevant code only; not a huge page without explanation).
Exactly what I was afraid off. Too much code, too little explanation. Try bringing this back to a few pages and methods to repro the problem. That makes it much easier for others to see what happens.

However, I still think the initial point is true: if databinding fires before SelectedIndexChanged fires, then either prevent databinding, or do it later.

Methods like Page_Init and Page_Load always *before* events like Click and SelectedIndexChanged. So, if you bind in those events, you overwrite your data and therefore prevent SelectedIndexChanged from firing.

Hope this helps,

Imar


---------------------------------------
Imar Spaanjaars
http://Imar.Spaanjaars.Com
Everyone is unique, except for me.
Author of Beginning ASP.NET 3.5 : in C# and VB, ASP.NET 2.0 Instant Results and Dreamweaver MX 2004
Want to be my colleague? Then check out this post.
  #7 (permalink)  
Old May 22nd, 2008, 08:28 AM
Authorized User
 
Join Date: Dec 2006
Location: , , .
Posts: 35
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Imar,

Thanks for your patience - I didn't expect the code to help but the whole exercise is helping me to see things a little more clearly.

I do understand the sequence of events which means that the data is bound before the event fires.

So, I have 2 custom controls (each defined in their own separate classes) - a drop down list and a placeholder for content - in home_page.aspx (home_page) and I want the binding of the placeholder to be dependant on the selected value of the drop down.

home_page inherits from a custom Page class which contains the event handler for the selectedIndexChanged event of the drop down - so would I be getting closer if I assumed that I can override Page's event handler in home_page, get the value of the drop down list there and bind the data to the placeholder at that point rather than in the home_page's OnLoad event handler?
  #8 (permalink)  
Old May 22nd, 2008, 08:46 AM
Imar's Avatar
Wrox Author
Points: 72,038, Level: 100
Points: 72,038, Level: 100 Points: 72,038, Level: 100 Points: 72,038, Level: 100
Activity: 100%
Activity: 100% Activity: 100% Activity: 100%
 
Join Date: Jun 2003
Location: Utrecht, Netherlands.
Posts: 17,080
Thanks: 80
Thanked 1,587 Times in 1,563 Posts
Default

It's difficult to answer that questions, as I don't fully see the whole picture.

What I would do is this:

1. Create a public event on the user control(s) like SelectedIndexChanged

2. In the SelectedIndexChanged of the DropDownList raise your custom SelectedIndexChanged event

3. In the page, register a handler for your custom SelectedIndexChanged of the UC

4. Inside this handler, determine what to do and rebind your data.

Hope this helps,

Imar

---------------------------------------
Imar Spaanjaars
http://Imar.Spaanjaars.Com
Everyone is unique, except for me.
Author of Beginning ASP.NET 3.5 : in C# and VB, ASP.NET 2.0 Instant Results and Dreamweaver MX 2004
Want to be my colleague? Then check out this post.
  #9 (permalink)  
Old May 22nd, 2008, 09:19 AM
Authorized User
 
Join Date: Dec 2006
Location: , , .
Posts: 35
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Epiphany Moment!

Imar - those four steps are exactly the way to do it.

I was getting so confused I thought I had to access the public event through the custom Page class - but of course the control is already in home_page so I can reference it directly from there.

Thanks very much for your help!


http://www.thewebsiteshop.co.uk
  #10 (permalink)  
Old May 22nd, 2008, 12:51 PM
Imar's Avatar
Wrox Author
Points: 72,038, Level: 100
Points: 72,038, Level: 100 Points: 72,038, Level: 100 Points: 72,038, Level: 100
Activity: 100%
Activity: 100% Activity: 100% Activity: 100%
 
Join Date: Jun 2003
Location: Utrecht, Netherlands.
Posts: 17,080
Thanks: 80
Thanked 1,587 Times in 1,563 Posts
Default

Excellent. So, as you pointed out, posting code added to the confusion indeed. However, it was that confusion that led me to post these four steps. Interesting how things can go.... ;)

Imar


---------------------------------------
Imar Spaanjaars
http://Imar.Spaanjaars.Com
Everyone is unique, except for me.
Author of Beginning ASP.NET 3.5 : in C# and VB, ASP.NET 2.0 Instant Results and Dreamweaver MX 2004
Want to be my colleague? Then check out this post.
 


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
SortCommend event is being fired twice anup_daware .NET Framework 2.0 2 August 9th, 2006 12:19 AM
SortCommend event is being fired twice anup_daware .NET Framework 1.x 1 August 4th, 2006 05:32 AM
fired event Sorting which wasn't handled fantef ASP.NET 2.0 Basics 0 July 27th, 2006 10:05 AM
Session_Start event not fired rl ASP.NET 1.0 and 1.1 Professional 20 February 22nd, 2005 04:29 PM
DataGrid SortCommand event not fired in UserContro vskumar ASP.NET 1.x and 2.0 Application Design 2 February 17th, 2005 08:06 AM



All times are GMT -4. The time now is 04:29 AM.


Powered by vBulletin®
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.