OK, so it has been a while since I have had my head down in some code but this one caught me off guard for a while.

I have two pages: default.aspx and report.aspx. On default.aspx I have a form with a couple of drop-downs and a Proceed button that performs a cross-page post-back to the report.aspx page. In the report.aspx page I then wanted to get at the controls in the previous page (i.e. default.aspx) to retrieve the selected indexes from the form. Following the documentation on MSDN, I used the PreviousPage property to get a reference to the source page and then tried to use FindControl to get a reference to the controls on the default.aspx page. However, while this did compile, it didn't actually find the controls from the source page.

From the MSDN documentation:

    if (Page.PreviousPage != null)
    {
       
TextBox SourceTextBox = (TextBox)Page.PreviousPage.FindControl("TextBox1");
       
if (SourceTextBox != null)
        {
            Label1.Text = SourceTextBox.Text;
        }
    }

   

The version from my code:

    if (Page.PreviousPage != null)
    {
       
DropDownList drpEntity = (DropDownList)Page.PreviousPage.FindControl("drpEntity");
       
DropDownList drpDate = (DropDownList)Page.PreviousPage.FindControl("drpDate");
       
if (drpDate != null && drpEntity != null)
        { ...

   

It turns out that since I am using Master Pages, this example does not apply. The Master Page contains a ContentPlaceHolder control which the content of my page is embedded in, I needed to get a reference to that first and then do the FindControl within the ContentPlaceHolder control.   

    if (Page.PreviousPage != null)
    {
       
ContentPlaceHolder cph1 = (ContentPlaceHolder)Page.PreviousPage.FindControl("contentplaceholder1");
       
if (cph1 != null)
        {
           
DropDownList drpEntity = (DropDownList)cph1.FindControl("drpEntity");
           
DropDownList drpDate = (DropDownList)cph1.FindControl("drpDate");
           
if (drpDate != null && drpEntity != null)
            { ...

This worked well enough, but now I wanted to go one step further. If you are sure that the only way to this page is from the previous one (default.aspx in my case) as a cross-page post-back or a server transfer you can get the cast the PreviousPage object to the actual class for that page, and reference the properties directly.

First you need to put a reference for the previous page's namespace in your page's ASPX file right under the <%@ Page

    <%@ PreviousPageType VirtualPath="~/default.aspx" %>


Now you need to expose the properties that you want to get to. Unfortunately the controls are not marked as public so directly referencing them will get you an "inaccessible due to its protection level" error. Instead just expose some public properties on the page that return the values you need. So in my Default.aspx:

    public partial class DefaultAspx : System.Web.UI.Page
    {
       
public string StartDate
        {
           
get { return FormatMyDate(drpDate.SelectedIndex); }
        }
       
public string EndDate
        {
           
get { return FormatMyDate(drpDate.SelectedIndex+1); }
        }
       
public string Entity
        {
           
get { return drpEntity.SelectedValue; }
        }

And that is it. Now you can get the PreviousPage property, cast it as the previous page's type and directly access the public properties you exposed in the previous code block.

   

    if (Page.PreviousPage != null && PreviousPage is DefaultAspx)
    {
       
if (Page.PreviousPage.IsCrossPagePostBack == true)
        {
           
string sStart = ((DefaultAspx)PreviousPage).StartDate;
           
string sEnd = ((DefaultAspx)PreviousPage).EndDate;
           
string entity = ((DefaultAspx)PreviousPage).Entity;

Works perfectly. Hopefully that helps at least one person out of a jam.

Mark