Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 248
  • Last Modified:

trying to construct a page from a header user control..

Here is my situation.
I have couple of pages-p1,p2,p3 .... All pages share the following structure-header,body,footer(header and footer are defined as user controls). In the header i have a small search box and a submit button. P1 is my home page, P2 has a detail search engine, p3 is some other page.I want no matter which page i am {p1,p2,p3}, whenver i type some text in the small-header search box and click the header submit button, i want to be able to automatically display the searched data on page p2-just as i would do if i had to search for the text on p2. You have to keep in mind that that header is a user controls and i can be on any page-p1,p2,p3-when i type the text and click submit i should automaically see the results on p2. The search engine alone works so i dont have a problem with it. I am just little confused how to link the header with page 2. I have couple of ideas in my mind. The easiest way is to send the search string as querry string  and redirect to p2, and on p2 to check if the querry exist and to proceed. However, i wanted to get more fancy. I want to learn the core of OOP in asp.net. I wanted to do something like that:
on_submit_button()   //On submit button for my header control
{
p2 newPage=new p2();
newPage.myDataGrid.DataSource=getDS("john doe"); //getDS  returns a dataset
newPage.myDataGrid.DataBind();
newPage.Page_Load();
}

ok i made most of things but my idea is that i want get more deep into OOP rather than relaying on session and querry strings. Or if you have different ideas please share with us..And if you have more question please ask me.
Thansk in advance.
0
Carl3003
Asked:
Carl3003
  • 8
  • 6
1 Solution
 
laotzi2000Commented:
You can declare a public click event for the header user control.
And the click event of the button on the header user control will fire the above click event.

Then in each page(p1,p2,p3) you can define a different search function and hook this
function up to the click event of the header user control.
This way, with different page, different function will be called when the button is clicked.
0
 
b1xml2Commented:
aspx
===
<%@ Page language="c#" Codebehind="Parent.aspx.cs" AutoEventWireup="false" Inherits="b1xml2.ExpertsExchange.CSharp.May.Parent" %>
<%@ Register TagPrefix="uc1" TagName="Header" Src="Header.ascx" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
  <HEAD>
    <title>Parent</title>
    <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
    <meta name="CODE_LANGUAGE" Content="C#">
    <meta name=vs_defaultClientScript content="JavaScript">
    <meta name=vs_targetSchema content="http://schemas.microsoft.com/intellisense/ie5">
  </HEAD>
  <body MS_POSITIONING="FlowLayout">
      
    <form id="Form1" method="post" runat="server">
<uc1:Header id="Header1" runat="server"></uc1:Header>

     </form>
      
  </body>
</HTML>


aspx.cs
====
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace b1xml2.ExpertsExchange.CSharp.May
{
      /// <summary>
      /// Summary description for Parent.
      /// </summary>
      public class Parent : System.Web.UI.Page
      {
            protected Header Header1;

            private void Page_Load(object sender, System.EventArgs e)
            {
                  // Put user code to initialize the page here
            }

            private void Page_Init(object sender,EventArgs e)
            {
                  Header1.Click += new EventHandler(Header1_Click);
            }

            #region Web Form Designer generated code
            override protected void OnInit(EventArgs e)
            {
                  //
                  // CODEGEN: This call is required by the ASP.NET Web Form Designer.
                  //
                  InitializeComponent();
                  base.OnInit(e);
            }
            
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {    
                  this.Load += new System.EventHandler(this.Page_Load);
                  this.Init += new System.EventHandler(this.Page_Init);
            }
            #endregion

            private void Header1_Click(object sender, EventArgs e)
            {
                  Response.Write("Header's Click Event Has Bubbled Up");
            }
      }
}

ascx
===
<%@ Control Language="c#" AutoEventWireup="false" Codebehind="Header.ascx.cs" Inherits="b1xml2.ExpertsExchange.CSharp.May.Header" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%>
<asp:Button ID="GoButton" Runat="server" Text="Go" />


ascx.cs
=====
namespace b1xml2.ExpertsExchange.CSharp.May
{
      using System;
      using System.Data;
      using System.Drawing;
      using System.Web;
      using System.Web.UI.WebControls;
      using System.Web.UI.HtmlControls;

      /// <summary>
      ///            Summary description for Header.
      /// </summary>
      public class Header : System.Web.UI.UserControl, IHeader
      {
            #region Click Event Optimised
            private static readonly object ClickEventHandlerKey = new object();

            public event EventHandler Click
            {
                  add { this.Events.AddHandler(ClickEventHandlerKey,value); }
                  remove { this.Events.RemoveHandler(ClickEventHandlerKey,value); }
            }

            private void OnClick()
            {
                  EventHandler handler = this.Events[ClickEventHandlerKey] as EventHandler;
                  if (handler != null)
                        handler(this,EventArgs.Empty);
            }
            #endregion

            protected System.Web.UI.WebControls.Button GoButton;

            private void Page_Load(object sender, System.EventArgs e)
            {
                  // Put user code to initialize the page here
            }

            private void Page_Init(object sender,EventArgs e)
            {
                  GoButton.Click += new EventHandler(GoButton_Click);
            }

            #region Web Form Designer generated code
            override protected void OnInit(EventArgs e)
            {
                  //
                  // CODEGEN: This call is required by the ASP.NET Web Form Designer.
                  //
                  InitializeComponent();
                  base.OnInit(e);
            }
            
            /// <summary>
            ///            Required method for Designer support - do not modify
            ///            the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
                  this.Load += new System.EventHandler(this.Page_Load);
                  this.Init += new System.EventHandler(this.Page_Init);

            }
            #endregion

            private void GoButton_Click(object sender, EventArgs e)
            {
                  OnClick();
            }
            }

      public interface IHeader
      {
            event EventHandler Click;
      }
}
0
 
b1xml2Commented:
Notes
====
1. Only in C#, can you use the add,remove keywords. This allows for the event to be created once per class, rather than once per instance. It is a recommended approach when creating custom, composite or server controls as well.
2. The interface IHeader can be very handy because you could conceivably have different headers at different parts of your application (who knows? but providing extensibility when it doesnt hurt is always a good idea!!). The interface will come in good for any other user controls on the page that wants to hook onto the click event of the user control. It is at this point that the other user controls should not need to know exactly what UserControl is acting as your header for the page.

Thus, on the main page this could also be done:
private IHeader header;

private void Page_Init(object sender,EventArgs e)
{
    this.header = Header1;
    this.header.Click += new EventHandler(Header1_Click);
}

with this, the other user controls now deal with header and not Header1;
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
Carl3003Author Commented:
b1xml2 ,
This is very interesting solution but how do you switch the parent page to the search page(p2)?
if my parent page is p1
search page is p2,
then if i am on p1 and click the header search control, i should be automatically redirected to p2 and display the search results.
The point is if i am on any page-p1,p3,p4 and if click the header button, i should be redirected to p2 and see the results on p2 only.
0
 
b1xml2Commented:
ah =)

inside the user control, you can do it in a couple of ways:
[pseudo-code]
1. Response.Redirect(ResolveUrl(string.Format("~/page2.aspx?Id={0}",this.defaultValue)),true);

2.
  user control
  ===========
  Context.Items["Id"] = this.defaultValue;
  Server.Transfer("page2.aspx",false);

  in page2.aspx
 ==========
 private bool IsServerTransfer
 {
   get { return (Context.Handler is this.Page); }
  }
 private void Page_Load(object sender,EventArgs e)
 {
    if ! this.IsPostBack && this.IsServerTransfer)
   {
     string Id = Context.Items["Id"].ToString();
   }
 }

 
 
0
 
Carl3003Author Commented:
in this way i am not going any far away than my original solution-using querry string or sessions to signal for search strings. But i guess  i want something which is not easily possible to do. I think i confused you when i said "redirect", what i really meant was to load p2 on the control's click_event.
Its like i am creating an instance of page2.aspx on-the-fly, and then i modify this instance by its databind function which populate its datagrid and  displays. So the user will really see page2 will search already done and results binded to datagrid.
0
 
b1xml2Commented:
the problem is the current request pipeline is streaming out data from page1. If you want, you;d have to use Server.Transfer

Page 2
======

private void Page_Load(object sender, EventArgs e)
{
  if (! this.IsPostBack && this.IsServerTransfer)
  {
    // now that you have the reference to Page1;
   // you can see the wisdom of implementation interfaces in Page1
   Page1 parent = Context.Handler as Page1;
   // access data in Page1
   // call database
   // populate grid in Page 2
   
  }
}

so even though this isnt a postback, you can grab data from Page1 and use that in Page 2
0
 
Carl3003Author Commented:
this function gives me some error message..
 private bool IsServerTransfer
 {
   get { return (Context.Handler is this.Page); }
  }
0
 
b1xml2Commented:
try this:

private bool IsServerTransfer
{
      get
      {
            bool value = false;
            if ((Page)Context.Handler is this.Page)
            {
                  value = true;
            }
            return value;
      }
 

}
0
 
Carl3003Author Commented:
i am getting the same error message as before:

error CS1525: Invalid expression term ')'
error CS1002: ; expected

Am i missing a reference or anything else?

These are my references:

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Data.OracleClient;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
0
 
b1xml2Commented:
sorry,

private bool IsServerTransfer
{
      get
      {
            return (Context.Handler is <name_of_class>);
      }
}

i.e.
return (Context.Handler is WebForm3);
0
 
Carl3003Author Commented:
is this ok?

            private bool IsServerTransfer
            {
                  get
                  {
                        return (Context.Handler is apsnet.controls.header);
                  }
            }
0
 
b1xml2Commented:
private bool IsServerTransfer
{
     get
     {
          return (Context.Handler is <name_of_class>);
     }
}

resides in the 2nd Page (aspx.cs)

and the name must be that of the 2nd Page
0
 
Carl3003Author Commented:
that worked but now i am facing another problem..

Object reference not set to an instance of an object.

if (!this.IsPostBack && IsServerTransfer)
{
      string s = Context.Items["search"].ToString(); // The error message refers to here
}
0
 
b1xml2Commented:
have you passed data from the main page??
as in PageA:
Context.Items["search"] = data;


and in PageB

if (! this.IsPostBack && this.IsServerTransfer)
{
  if (Context.Items.Contains("search"))
  {
     string search = Context.Items["search"].ToString();
  }
}
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 8
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now