Hi Natty:
Was able to analyse your code, and I do understand the notion of injecting
prefix and suffix code around the base.Render(wri ter); statement.
But that -- although simple enough to accomplish -- completly destroys any
chance of injecting working buttons above and below.
What I am saying is that what I would like to accomplish is the following:
writer.Write("< div stuff above the enherited controls/><asp:button
runat=server onClick=ClickMe ......./>");
base.Render(wri ter);
writer.Write("< asp:button runat=server... ../></div>");
but obviously since these were injected after InstantiateCont rols(), they
are completly 'dead'.
They appear as buttons (maybe) but have never been delegated back to the
forms attached ClickMe1() event...
Parts of the puzzle that I have figured out to doing this include the
following steps...
Create and instantiate controls dynamically within the OnInit() event so
that later InstantiateCont rols() wires them up correctly to be
parts of the webform's visualstate,etc . wiring.
Just before getting out of OnInit() -- one has to move the descendant
Controls INTO the container we want -- by a combination of
Remove() and AddAt().
So far so good. If we stopped here, we would have mostly all the parts of
visual enheritence.
The only problem is that any controls created dynamically in the descendant
control -- such as the TextBox control you created in the descendant's
OnLoad() -- would not exist at this point, and therefore could not be moved
into place...
So, in the Render() event we have to repeat the Remove/AddAt process
here...(for some reason, it doesn't work at all if you don't do the
Add/Remove
loop in the OnInit()...noth ing shows up on page).
At this point with the base classes code below, I have got the controls to
show up in the right place -- and correctly wired...but...w ell...I'm not
satisfied.
"What?! It works! Move on!" Yeah...well...t rue...but I don't understand
really why it works. Which means that I will lose a ton of time again on
another
project, repeating all my mistakes...etc.
So I have two questions.
a) In the OnInit() event, when I've created all the new controls dynamically
BUT NOT ADDED them to the page -- and you have only one DropDownList
in yours, does it report that Controls.Count = 2??? More disturbing, if you
look at their ID's..why are they BOTH THE SAME element?!?!
b) Why does this solution fail if I do not do the Loop/AddAt() -- to move
the children controls into the right location -- in BOTH OnInit and later
Render().
It appears to me that it should work fine if I just put it in the Render()
event. no?
c) And how could I improve the loop mechanism? In other words -- if class b
enherits from a -- is there any way that I can distinguish a.class[0] as
being from a rather than b? "wot?!" ...I think if you look at the loop you
will understand:
for (int i=(Controls.Cou nt-1);i>-1;i--)
{
tC = Controls[i];
if ((tC != ID_DivOuter) && (ID_DivLower.Co ntrols.Contains (tC)==false))
{
try
{
// Controls.Remove (tC);
ID_DivLower.Con trols.AddAt(0,t C);
}
catch {
s = "SHIT! " + tC.GetType().To String();
}
}
}
Ok. The full class that works...but still puzzles me, is here:
namespace WebApplication3
{
using System;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.UI.W ebControls;
using System.Web.UI.H tmlControls;
/// <summary>
/// Summary description for baseUC.
/// </summary>
public class baseUC : System.Web.UI.U serControl
{
private System.Collecti ons.ArrayList _SubControls;
protected System.Web.UI.W ebControls.Imag eButton ID_ExpandBtn;
protected System.Web.UI.H tmlControls.Htm lGenericControl ID_DivOuter;
protected System.Web.UI.H tmlControls.Htm lGenericControl ID_DivUpper;
protected System.Web.UI.H tmlControls.Htm lGenericControl ID_DivLower;
public bool Expanded = true;
public bool Editable = true;
public string BgColor="";
public string Header="";
public string Subject="";
public string Body = "";
public System.Collecti ons.ArrayList SubControls = new
System.Collecti ons.ArrayList() ;
public System.Web.UI.C ontrol SubControl = null;
public string SubControlSrc=" ";
private void Page_Load(objec t sender, System.EventArg s e)
{
// Put user code to initialize the page here
if (Session[this.UniqueID + "Expanded"]==null){Session[this.UniqueID +
"Expanded"] = Expanded;}
Expanded = (bool)Session[this.UniqueID + "Expanded"];
}
#region Web Form Designer generated code
override protected void OnInit(EventArg s e)
{
//Because the *.ascx file will be ignored, and therefore any and all
//html elements put here, this base classe's html and buttons need to
//created dynamically here:
//Another point: it needs to be created Here -- because if you make and
inject
//them into the page after InitializeCompo nent runs, you will get buttons --
but
//they won't be wired up into the event handling so are useless.
//Preamble:
//at the top of the page there are the following protected global vars
//so that Render event can re-access what is created here:
//protected System.Web.UI.W ebControls.Imag eButton ID_ExpandBtn;
//protected System.Web.UI.H tmlControls.Htm lGenericControl ID_DivOuter;
//protected System.Web.UI.H tmlControls.Htm lGenericControl ID_DivUpper;
//protected System.Web.UI.H tmlControls.Htm lGenericControl ID_DivLower;
//Declare local vars:
System.Web.UI.H tmlControls.Htm lGenericControl oDivOuter;
System.Web.UI.H tmlControls.Htm lGenericControl oDivUpper;
System.Web.UI.H tmlControls.Htm lGenericControl oDivLower;
System.Web.UI.H tmlControls.Htm lTable oTable;
System.Web.UI.H tmlControls.Htm lTableRow oRow;
System.Web.UI.H tmlControls.Htm lTableCell oCell;
System.Web.UI.W ebControls.Imag eButton oImg;
System.Web.UI.H tmlControls.Htm lGenericControl oBR;
System.Web.UI.C ontrol tC;
string s;
//Create the Outer div, that will contain two inner divs:
oDivOuter = ID_DivOuter = new
System.Web.UI.H tmlControls.Htm lGenericControl ();
oDivOuter.TagNa me = "div";
oDivOuter.ID = "DivOuter";
//Create the Upper-Inner div that will contain a table
//to hold icons, and container "Toolbar/Title"
oDivUpper = new System.Web.UI.H tmlControls.Htm lGenericControl ();
oDivUpper.TagNa me = "div";
oDivUpper.ID = "ID_DivUppe r";
oDivUpper.Attri butes.Add("clas s","HEADER GRADIENT");
oDivOuter.Contr ols.Add(oDivUpp er);
oTable=new System.Web.UI.H tmlControls.Htm lTable();
oTable.Border = 1;
oTable.ID ="TheTable";
oTable.Style.Ad d("width","100% ");
oTable.Style.Ad d("background-color","#A0FFA0 ");
oDivUpper.Contr ols.Add(oTable) ;
oRow = new System.Web.UI.H tmlControls.Htm lTableRow();
oRow.ID = "TheRow";
oTable.Rows.Add (oRow);
oCell = new System.Web.UI.H tmlControls.Htm lTableCell();
oCell.Attribute s.Add ("style","margi n:0;padding:0;w idth:1;");
oCell.ID = "TheCell";
oRow.Cells.Add( oCell);
//Put the Expand/Collapse Icon in cell 1:
oImg = ID_ExpandBtn = new System.Web.UI.W ebControls.Imag eButton();
oImg.ID = "TheImg";
oImg.ID = "ID_ExpandB tn";
ID_ExpandBtn.Cl ick += new System.Web.UI.I mageClickEventH andler
(OnClick_Expand Me);
oImg.Attributes .Add("style","c ursor:hand;widt h:16px;height:1 6px;margin:0;pa d
ding:0;margin-left:4px;border :0;");
oImg.Attributes["title"]= "Expanded:"+Exp anded.ToString( );
oCell.Controls. Add(oImg);
//Put the Container's Title in Cell2:
oCell = new System.Web.UI.H tmlControls.Htm lTableCell();
oCell.InnerHtml = this.Subject; //Set text of Container TitleBar
oRow.Cells.Add( oCell);
//Move on to the Inner-Bottom Div -- in which we want to inject sub
controls...
oDivLower = ID_DivLower = new
System.Web.UI.H tmlControls.Htm lGenericControl ();
oDivLower.TagNa me = "div";
oDivLower.ID = "ID_DivLowe r";
oDivLower.Style .Add("backgroun d-color","#A0A0FF ");
oDivLower.Inner Text = "This is the lower div... where the controls should
end up!";
oDivOuter.Contr ols.Add(oDivLow er);
//Close with a break so that each control lines up vertically within the
uc_page_panel.a scx
oBR = new System.Web.UI.H tmlControls.Htm lGenericControl ();
oBR.TagName = "br";
oBR.ID = "TheBR";
oDivOuter.Contr ols.Add(oBR);
int tTest = Controls.Count;
//WHY is tTEST=2 ??? I only have one enherited control visible from this
page at this point
//in time. Plus! both appears to be the same control...
for (int i=0;i<Controls. Count;i++)
{
tC = Controls[i];
s=(tC.ID);
}
//Move any controls already created in children into this component...
//***DESIGN FLAW***:
//But if you do it here, you won't catch any controls dynamically injected
//later by descendant control
//One other point. It's wierd, but if you remove this code, and rely on
doing
//it all in the Render() event -- you won't get squat. It seems you have to
//do it in 2 'halves'...one here, one repeat job in Render()
int iMax = Controls.Count -1;
for (int i=iMax;i>-1;i--)
{
tC = Controls[i];
//Remove from Controls -- and inject into one only:
// this.Controls.R emove(tC);
ID_DivLower.Con trols.AddAt(0,t C);
}
this.Controls.A dd(oDivOuter);
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeCompo nent();
base.OnInit(e);
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeCompo nent()
{
this.Load += new System.EventHan dler(this.Page_ Load);
// this.PreRender += new System.EventHan dler(this.Page_ PreRender);
}
public void OnClick_ExpandM e(object sender,
System.Web.UI.I mageClickEventA rgs e)
{
Expanded = ! Expanded;
Session[this.UniqueID + "Expanded"] = Expanded;
}
private void Page_PreRender( object sender, System.EventArg s e)
{
}
protected override void Render(System.W eb.UI.HtmlTextW riter writer)
{
//We 'could' use the PreRender event to do this -- but then we would have to
wire in
//all descendant controls to point to it?
if (Expanded)
{
ID_ExpandBtn.Im ageUrl =
"http://localhost/xlib/xlib_graphics/btn13/btn13_arrow_1a_ down.gif";
ID_DivLower.Sty le["display"] = "inline";
}
else
{
ID_ExpandBtn.Im ageUrl =
"http://localhost/xlib/xlib_graphics/btn13/btn13_arrow_1a_ right.gif";
ID_DivLower.Sty le["display"] = "none";
}
System.Web.UI.C ontrol tC;
string s = "";
for (int i=(Controls.Cou nt-1);i>-1;i--)
{
tC = Controls[i];
if ((tC != ID_DivOuter) && (ID_DivLower.Co ntrols.Contains (tC)==false))
{
try
{
// Controls.Remove (tC);
ID_DivLower.Con trols.AddAt(0,t C);
}
catch {
s = "ERROR! " + tC.GetType().To String();
}
}
}
/*
* MS SaMPLE:
if (HasControls()) {
for (int i=0; i < Controls.Count; i++) {
Controls[i].RenderControl( writer);
}
}
*/
base.Render(wri ter);
}
#endregion
}
}
"Natty Gur" <na***@dao2com. com> wrote in message
news:%2******** ********@TK2MSF TNGP11.phx.gbl. ..
Hi,
e-amil me and i'll return a demo project ....
Natty Gur[MVP]
blog : http://weblogs.asp.net/ngur
Mobile: +972-(0)58-888377
*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!