![]() |
help: question about LifeCycle for controls that change the 'shape' of their control tree?
Hello:
All the books I have looked at about how to design custom composite server controls talk about the LifeCycle..and although most is quite clear, there is one nagging type of control creation that I am looking for clarification about...Can anyone help? The following example is a trivial one, but shows the point hopefully clearly: It's a Table of two cells, that has an ImageLocation property which determines if the layout should be flipped (image on left, text on right): CustomHeader():WebControl{ //Protected Elements HtmlRow ROW; HtmlCell CELL1; HtmlCell CELL2; Label HEADER; Image LOGO //Private fields: string _HeaderText; string _ImgUrl; eAlign _ImageLocation = eAlign.Right; //Public Properties to access Private Fields: string HeaderText {get {return _HeaderText;}set{_HeaderText;}} //etc..... //Constructor CustomHeader():base{} Init (){ EnsureCreateControls(); } //LifeCycle CreateChildControls { oTable = new Table(); ROW = new TableRow(); oTable.Rows.Add(oRow); CELL1 = new TableCell(); CELL2 = new TableCell2(); IMG = new Image(); if (_ImageLocation == eAlign.Left){ CELL1.Controls.Add(oImg);CELL2.Controls.Add(new LiteralControl(_HeaderText)); }else{ CELL2.Controls.Add(oImg);CELL1.Controls.Add(new LiteralControl(_HeaderText)); } //etc... } With the above scenario, I have several questions: a) This would work if the control is the public properties were set in the IDE via HTML, because the Public 'Align' property would be set BEFORE the CreateControls was called -- the page lifecyle would be * Set Private Fields * Constructor * Set Public Properties from the HTML -- ie the Align * Init * CreateChildControls. But this would fail if mucked around with via code, such as this on the page that instantiates the controls * MyControl oC = new MyControl(); * Page.Controls.Add(oC); //Triggers Init, OnLoad, and therefore CreateChildControls...the shape is using the default align=left... * oC.ImageLocation = eAlign.Right; * Result: WRONG LAYOUT!!!! (Still Left instead of new Right). The obvious answer I will probably get is ('don't set public properties once added to the page')....But there are times when this is required...plus, I don't see anywhere in the books where it was stated that Controls, once added to the page, should not be touched. Seems to not be so 'dynamic' if that is the case... One way I've seen mentioned is to ...Rebuild everything...YIKES!: Public eAlign ImageLocation {get {_ImageLocation;}set {Controls.Clear()ChildControlsCreated=false; and re-EnsureChildControls().}} This seems to be completly nutty...build a tree, to throw it away, and start again... So... A work around seems to break the rendering into two parts: use the CreateChildControls to create all the necessary components -- but not finish the Tree until the PreRender stage: CreateChildControls { oTable = new Table();this.Controls.Add(oTable); ROW = new TableRow(); oTable.Rows.Add(oRow); CELL1 = new TableCell(); CELL2 = new TableCell2(); IMG = new Image(); //STOP HERE!!! NEXT PART IS DONE ONLY IN PAGE_PRERENDER LATER } Page_PreRender(){ if (_ImageLocation == eAlign.Left){ oCell1.Controls.Add(oImg);oCell2.Controls.Add(new LiteralControl(_HeaderText)); }else{ oCell2.Controls.Add(oImg);oCell1.Controls.Add(new LiteralControl(_HeaderText)); } //Good place to apply any custom styling too... } But NONE of the books seem to use the PreRender event -- in fact, it almost looks like they steer away from it...Any reason why? Finally -- one last dumb question. I see a lot of Examples/books/articles stating that all get/set properties talking directly to a sub element should have EnsureChildControls in front of it: string Text {get {EnsureChildControls();return _TEXTBOX.Text;} set {EnsureChildControls();_TEXTBOX.Text=value}} Ok...maybe this is just me...but We're talking about using a function jump, which checks a boolean property get function which covers a private field...for EVERY public property that is set....Isn't this overkill???? Would it not be better to get this work out of the way as soon as possible, once, and to not have to call EnsureChildControls() all the time? How about doing it at the earliest possible time -- in the Constructor: MyControl : WebControl{ //Constructor MyControl():base(){ //Private Fields have been intialized already //but no public properties have been called yet, so it's the right time to do this: EnsureChildControls(); } ...... } My question: I get worried when I see that i am the only person doing something ;-)....and I can't find a single person who is using EnsureChildControls() in the constructor.... Is there any practical reason that it is too early? I know that I they won't be rehydrated yet, until the Page_Load(), but that's ok. I just need to be able to get rid of EnsureChildControls() being everywhere. Thank you kindly for any advice you may have on how find the 'perfect' recipie for building custom controls... ;-) Sky |
Re: question about LifeCycle for controls that change the 'shape' of their control tree?
Your thinking is great but remember there is another property called
ChildControlsCreated, which you should set to true in your CreateChildControls at the end. So consecutive calls to EnsureChildControls won't actually rebuild the control tree. EnsureChildControls is a method that just checks that control tree is created. And it checks the above boolean property. So whenever you do something on the control (set/get some property that should access any control within the tree), you should call EnsureChildControls() method. Actually when page is rendering it also calls EnsureChildControls recursively on it's controls. So all controls are valid before rendering and before the response is sent to the client all controls have a true value in childcontrolscreated property. -- RobertK { Clever? No just smart. } "Sky" <forums@xact-solutions.removethis.com> wrote in message news:OjbHOspXEHA.1000@TK2MSFTNGP12.phx.gbl... > Hello: > > All the books I have looked at about how to design custom composite server > controls talk about the LifeCycle..and although most is quite clear, there > is one nagging type of control creation that I am looking for clarification > about...Can anyone help? > > The following example is a trivial one, but shows the point hopefully > clearly: It's a Table of two cells, that has an ImageLocation property which > determines if the layout should be flipped (image on left, text on right): > > CustomHeader():WebControl{ > //Protected Elements > HtmlRow ROW; > HtmlCell CELL1; > HtmlCell CELL2; > Label HEADER; > Image LOGO > > //Private fields: > string _HeaderText; > string _ImgUrl; > eAlign _ImageLocation = eAlign.Right; > > //Public Properties to access Private Fields: > string HeaderText {get {return _HeaderText;}set{_HeaderText;}} > //etc..... > > //Constructor > CustomHeader():base{} > > Init (){ > EnsureCreateControls(); > } > > //LifeCycle > CreateChildControls { > oTable = new Table(); > ROW = new TableRow(); > oTable.Rows.Add(oRow); > CELL1 = new TableCell(); > CELL2 = new TableCell2(); > > IMG = new Image(); > > if (_ImageLocation == eAlign.Left){ > CELL1.Controls.Add(oImg);CELL2.Controls.Add(new > LiteralControl(_HeaderText)); > }else{ > CELL2.Controls.Add(oImg);CELL1.Controls.Add(new > LiteralControl(_HeaderText)); > } > //etc... > } > > > > With the above scenario, I have several questions: > > a) This would work if the control is the public properties were set in the > IDE via HTML, because the Public 'Align' property would be set BEFORE the > CreateControls was called -- the page lifecyle would be > * Set Private Fields > * Constructor > * Set Public Properties from the HTML -- ie the Align > * Init > * CreateChildControls. > > But this would fail if mucked around with via code, such as this on the page > that instantiates the controls > * MyControl oC = new MyControl(); > * Page.Controls.Add(oC); //Triggers Init, OnLoad, and therefore > CreateChildControls...the shape is using the default align=left... > * oC.ImageLocation = eAlign.Right; > * Result: WRONG LAYOUT!!!! (Still Left instead of new Right). > > > The obvious answer I will probably get is ('don't set public properties once > added to the page')....But there are times when this is required...plus, I > don't see anywhere in the books where it was stated that Controls, once > added to the page, should not be touched. Seems to not be so 'dynamic' if > that is the case... > > One way I've seen mentioned is to ...Rebuild everything...YIKES!: > Public eAlign ImageLocation {get {_ImageLocation;}set > {Controls.Clear()ChildControlsCreated=false; and re-EnsureChildControls().}} > This seems to be completly nutty...build a tree, to throw it away, and start > again... > > > > > > So... > A work around seems to break the rendering into two parts: use the > CreateChildControls to create all the necessary components -- but not finish > the Tree until the PreRender stage: > > CreateChildControls { > oTable = new Table();this.Controls.Add(oTable); > ROW = new TableRow(); > oTable.Rows.Add(oRow); > CELL1 = new TableCell(); > CELL2 = new TableCell2(); > > IMG = new Image(); > //STOP HERE!!! NEXT PART IS DONE ONLY IN PAGE_PRERENDER LATER > } > > Page_PreRender(){ > if (_ImageLocation == eAlign.Left){ > oCell1.Controls.Add(oImg);oCell2.Controls.Add(new > LiteralControl(_HeaderText)); > }else{ > oCell2.Controls.Add(oImg);oCell1.Controls.Add(new > LiteralControl(_HeaderText)); > } > //Good place to apply any custom styling too... > } > > > But NONE of the books seem to use the PreRender event -- in fact, it almost > looks like they steer away from it...Any reason why? > > > > > > Finally -- one last dumb question. I see a lot of Examples/books/articles > stating that all get/set properties talking directly to a sub element should > have EnsureChildControls in front of it: > > string Text {get {EnsureChildControls();return _TEXTBOX.Text;} set > {EnsureChildControls();_TEXTBOX.Text=value}} > > Ok...maybe this is just me...but We're talking about using a function jump, > which checks a boolean property get function which covers a private > field...for EVERY public property that is set....Isn't this overkill???? > Would it not be better to get this work out of the way as soon as possible, > once, and to not have to call EnsureChildControls() all the time? > How about doing it at the earliest possible time -- in the Constructor: > > MyControl : WebControl{ > //Constructor > MyControl():base(){ > //Private Fields have been intialized already > //but no public properties have been called yet, so it's the right time > to do this: > EnsureChildControls(); > } > ..... > > } > > > My question: I get worried when I see that i am the only person doing > something ;-)....and I can't find a single person who is using > EnsureChildControls() in the constructor.... Is there any practical reason > that it is too early? > I know that I they won't be rehydrated yet, until the Page_Load(), but > that's ok. I just need to be able to get rid of EnsureChildControls() being > everywhere. > > > > > > Thank you kindly for any advice you may have on how find the 'perfect' > recipie for building custom controls... ;-) > Sky > > > > > > > > > > > > > > |
Re: question about LifeCycle for controls that change the 'shape' of their control tree?
Robert -- thanks for your response ;-)
Yes -- I did know about the EnsureChildControls() combo with the ChildControls Created bool... Which by the way seems to do more than just cover up a private bool -- I noticed that if I CreateChildControls, and not set ChildControlsCreatedExplicitly, and not call base.CreateChildControls(), the ChildControlsCreated is set automatically (!!!). How, where, I don't know... Maybe the code behind ChildControlsCreated looks something like get { return (_ChildControlsCreated)||(this.Controls.Count>0);} That aside, it still means that everytime EnsureChildControls is used in a property get/set, one is adding a lot of jumping around and checking, for something, that in my mind, should already have been taken care of... What i mean is that the code that is happening is something like: string MyProp(){ get { EnsureChildControls(); //which does * jump to addr of EnsureChildControls() * if ((ChildControlsCreated)||this.Controls.Count>0)){r eturn true;}else{CreateChildControls();} //back to your code: //etc. } } In other words -- its still atleast one addr jump, with all that the Stack/Reflection stuff of C# does... -- a conditional, a possible iterator creation, a count, then return... Now, I know that I am really being a pain in the bum asking about a realy small little waste of bytes -- but I am asking for the sake of getting a good grip on the life-cycle -- because as far as I can tell , 3 books = 3 different understandings !.... It seems that there is a lot of confusion out there about how to make a webcontrol be as flexible as a form control... Or..which is what I suspect -- it's not the books, it's me who is confused -- hence the questions ;-) PS: What were your thoughts as to what I am doing about breaking up the rendering into two parts (CreateChildControls/PreRender)? I'm working out here alone at home and have little contact with other asp.net programmers, so most of my methodology is home - brew...And sometimes, it gets so hard to do something, that I start wondering if I am totally looking at the whole thing from the wrong angle .... Very best, Sky "Robert Koritnik" <robert.koritnik.removethis@avtenta.si> wrote in message news:OxRf8S0XEHA.808@tk2msftngp13.phx.gbl... > Your thinking is great but remember there is another property called > ChildControlsCreated, which you should set to true in your > CreateChildControls at the end. So consecutive calls to EnsureChildControls > won't actually rebuild the control tree. > > EnsureChildControls is a method that just checks that control tree is > created. And it checks the above boolean property. So whenever you do > something on the control (set/get some property that should access any > control within the tree), you should call EnsureChildControls() method. > > Actually when page is rendering it also calls EnsureChildControls > recursively on it's controls. So all controls are valid before rendering and > before the response is sent to the client all controls have a true value in > childcontrolscreated property. > > -- > RobertK > { Clever? No just smart. } > > "Sky" <forums@xact-solutions.removethis.com> wrote in message > news:OjbHOspXEHA.1000@TK2MSFTNGP12.phx.gbl... > > Hello: > > > > All the books I have looked at about how to design custom composite server > > controls talk about the LifeCycle..and although most is quite clear, there > > is one nagging type of control creation that I am looking for > clarification > > about...Can anyone help? > > > > The following example is a trivial one, but shows the point hopefully > > clearly: It's a Table of two cells, that has an ImageLocation property > which > > determines if the layout should be flipped (image on left, text on right): > > > > CustomHeader():WebControl{ > > //Protected Elements > > HtmlRow ROW; > > HtmlCell CELL1; > > HtmlCell CELL2; > > Label HEADER; > > Image LOGO > > > > //Private fields: > > string _HeaderText; > > string _ImgUrl; > > eAlign _ImageLocation = eAlign.Right; > > > > //Public Properties to access Private Fields: > > string HeaderText {get {return _HeaderText;}set{_HeaderText;}} > > //etc..... > > > > //Constructor > > CustomHeader():base{} > > > > Init (){ > > EnsureCreateControls(); > > } > > > > //LifeCycle > > CreateChildControls { > > oTable = new Table(); > > ROW = new TableRow(); > > oTable.Rows.Add(oRow); > > CELL1 = new TableCell(); > > CELL2 = new TableCell2(); > > > > IMG = new Image(); > > > > if (_ImageLocation == eAlign.Left){ > > CELL1.Controls.Add(oImg);CELL2.Controls.Add(new > > LiteralControl(_HeaderText)); > > }else{ > > CELL2.Controls.Add(oImg);CELL1.Controls.Add(new > > LiteralControl(_HeaderText)); > > } > > //etc... > > } > > > > > > > > With the above scenario, I have several questions: > > > > a) This would work if the control is the public properties were set in the > > IDE via HTML, because the Public 'Align' property would be set BEFORE the > > CreateControls was called -- the page lifecyle would be > > * Set Private Fields > > * Constructor > > * Set Public Properties from the HTML -- ie the Align > > * Init > > * CreateChildControls. > > > > But this would fail if mucked around with via code, such as this on the > page > > that instantiates the controls > > * MyControl oC = new MyControl(); > > * Page.Controls.Add(oC); //Triggers Init, OnLoad, and therefore > > CreateChildControls...the shape is using the default align=left... > > * oC.ImageLocation = eAlign.Right; > > * Result: WRONG LAYOUT!!!! (Still Left instead of new Right). > > > > > > The obvious answer I will probably get is ('don't set public properties > once > > added to the page')....But there are times when this is required...plus, I > > don't see anywhere in the books where it was stated that Controls, once > > added to the page, should not be touched. Seems to not be so 'dynamic' if > > that is the case... > > > > One way I've seen mentioned is to ...Rebuild everything...YIKES!: > > Public eAlign ImageLocation {get {_ImageLocation;}set > > {Controls.Clear()ChildControlsCreated=false; and > re-EnsureChildControls().}} > > This seems to be completly nutty...build a tree, to throw it away, and > start > > again... > > > > > > > > > > > > So... > > A work around seems to break the rendering into two parts: use the > > CreateChildControls to create all the necessary components -- but not > finish > > the Tree until the PreRender stage: > > > > CreateChildControls { > > oTable = new Table();this.Controls.Add(oTable); > > ROW = new TableRow(); > > oTable.Rows.Add(oRow); > > CELL1 = new TableCell(); > > CELL2 = new TableCell2(); > > > > IMG = new Image(); > > //STOP HERE!!! NEXT PART IS DONE ONLY IN PAGE_PRERENDER LATER > > } > > > > Page_PreRender(){ > > if (_ImageLocation == eAlign.Left){ > > oCell1.Controls.Add(oImg);oCell2.Controls.Add(new > > LiteralControl(_HeaderText)); > > }else{ > > oCell2.Controls.Add(oImg);oCell1.Controls.Add(new > > LiteralControl(_HeaderText)); > > } > > //Good place to apply any custom styling too... > > } > > > > > > But NONE of the books seem to use the PreRender event -- in fact, it > almost > > looks like they steer away from it...Any reason why? > > > > > > > > > > > > Finally -- one last dumb question. I see a lot of Examples/books/articles > > stating that all get/set properties talking directly to a sub element > should > > have EnsureChildControls in front of it: > > > > string Text {get {EnsureChildControls();return _TEXTBOX.Text;} set > > {EnsureChildControls();_TEXTBOX.Text=value}} > > > > Ok...maybe this is just me...but We're talking about using a function > jump, > > which checks a boolean property get function which covers a private > > field...for EVERY public property that is set....Isn't this overkill???? > > Would it not be better to get this work out of the way as soon as > possible, > > once, and to not have to call EnsureChildControls() all the time? > > How about doing it at the earliest possible time -- in the Constructor: > > > > MyControl : WebControl{ > > //Constructor > > MyControl():base(){ > > //Private Fields have been intialized already > > //but no public properties have been called yet, so it's the right > time > > to do this: > > EnsureChildControls(); > > } > > ..... > > > > } > > > > > > My question: I get worried when I see that i am the only person doing > > something ;-)....and I can't find a single person who is using > > EnsureChildControls() in the constructor.... Is there any practical reason > > that it is too early? > > I know that I they won't be rehydrated yet, until the Page_Load(), but > > that's ok. I just need to be able to get rid of EnsureChildControls() > being > > everywhere. > > > > > > > > > > > > Thank you kindly for any advice you may have on how find the 'perfect' > > recipie for building custom controls... ;-) > > Sky > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
Re: question about LifeCycle for controls that change the 'shape' of their control tree?
About two step WebControl creation is a smart thing. Actually I had the same
thing in mind once. First you have to create those controls that will be in question when ProcessViewState phase begins. That's what you wanted to do. The second part in PreRender should position those already created controls into new containers. Seem reasonable. I once tried to do the same thing, but eventualy gave up, because I work in a multi developer environment and it would probably confuse others that would be (maybe) reediting my custom control. there's also a great article on ViewState, which also covers some of the very interesting part of the control's lifecycle: http://msdn.microsoft.com/library/de...nlifecycle.asp The other thing about ChildControlsCreated is somewhere else I think. I also saw, that EnsureChildControls gets executed even if you don't Create them and set childcontrolscreated to true. To me it looked more like (not like your get { checking two conditions}) checking the private bool and if false calling ensureChildControls and thus making it true. Because I did something like that. I created CreateChildControls, but I didn't call it in any method or property set/get. But in the end my webcontrol got created WITH CreateChildControls method. Looks like that a Page object before responding back (probably just before SaveViewState) calls EnsureChildControls recursively over all its containing controls. -- RobertK { Clever? No just smart. } "Sky" <forums@xact-solutions.removethis.com> wrote in message news:uaMdU3#XEHA.3120@TK2MSFTNGP12.phx.gbl... > Robert -- thanks for your response ;-) > Yes -- I did know about the EnsureChildControls() combo with the > ChildControls Created bool... > Which by the way seems to do more than just cover up a private bool -- I > noticed that if I CreateChildControls, and not set > ChildControlsCreatedExplicitly, and not call base.CreateChildControls(), the > ChildControlsCreated is set automatically (!!!). How, where, I don't know... > Maybe the code behind ChildControlsCreated looks something like > > get { return (_ChildControlsCreated)||(this.Controls.Count>0);} > > That aside, it still means that everytime EnsureChildControls is used in a > property get/set, one is adding a lot of jumping around and checking, for > something, that in my mind, should already have been taken care of... What i > mean is that the code that is happening is something like: > > string MyProp(){ > get { > EnsureChildControls(); > //which does > * jump to addr of EnsureChildControls() > * if ((ChildControlsCreated)||this.Controls.Count>0)){r eturn > true;}else{CreateChildControls();} > //back to your code: > //etc. > } > } > In other words -- its still atleast one addr jump, with all that the > Stack/Reflection stuff of C# does... -- a conditional, a possible iterator > creation, a count, then return... > > Now, I know that I am really being a pain in the bum asking about a realy > small little waste of bytes -- but I am asking for the sake of getting a > good grip on the life-cycle -- because as far as I can tell , 3 books = 3 > different understandings !.... It seems that there is a lot of confusion > out there about how to make a webcontrol be as flexible as a form control... > Or..which is what I suspect -- it's not the books, it's me who is > confused -- hence the questions ;-) > > > PS: What were your thoughts as to what I am doing about breaking up the > rendering into two parts (CreateChildControls/PreRender)? I'm working out > here alone at home and have little contact with other asp.net programmers, > so most of my methodology is home - brew...And sometimes, it gets so hard to > do something, that I start wondering if I am totally looking at the whole > thing from the wrong angle .... > > Very best, > Sky > > > > > > "Robert Koritnik" <robert.koritnik.removethis@avtenta.si> wrote in message > news:OxRf8S0XEHA.808@tk2msftngp13.phx.gbl... > > Your thinking is great but remember there is another property called > > ChildControlsCreated, which you should set to true in your > > CreateChildControls at the end. So consecutive calls to > EnsureChildControls > > won't actually rebuild the control tree. > > > > EnsureChildControls is a method that just checks that control tree is > > created. And it checks the above boolean property. So whenever you do > > something on the control (set/get some property that should access any > > control within the tree), you should call EnsureChildControls() method. > > > > Actually when page is rendering it also calls EnsureChildControls > > recursively on it's controls. So all controls are valid before rendering > and > > before the response is sent to the client all controls have a true value > in > > childcontrolscreated property. > > > > -- > > RobertK > > { Clever? No just smart. } > > > > "Sky" <forums@xact-solutions.removethis.com> wrote in message > > news:OjbHOspXEHA.1000@TK2MSFTNGP12.phx.gbl... > > > Hello: > > > > > > All the books I have looked at about how to design custom composite > server > > > controls talk about the LifeCycle..and although most is quite clear, > there > > > is one nagging type of control creation that I am looking for > > clarification > > > about...Can anyone help? > > > > > > The following example is a trivial one, but shows the point hopefully > > > clearly: It's a Table of two cells, that has an ImageLocation property > > which > > > determines if the layout should be flipped (image on left, text on > right): > > > > > > CustomHeader():WebControl{ > > > //Protected Elements > > > HtmlRow ROW; > > > HtmlCell CELL1; > > > HtmlCell CELL2; > > > Label HEADER; > > > Image LOGO > > > > > > //Private fields: > > > string _HeaderText; > > > string _ImgUrl; > > > eAlign _ImageLocation = eAlign.Right; > > > > > > //Public Properties to access Private Fields: > > > string HeaderText {get {return _HeaderText;}set{_HeaderText;}} > > > //etc..... > > > > > > //Constructor > > > CustomHeader():base{} > > > > > > Init (){ > > > EnsureCreateControls(); > > > } > > > > > > //LifeCycle > > > CreateChildControls { > > > oTable = new Table(); > > > ROW = new TableRow(); > > > oTable.Rows.Add(oRow); > > > CELL1 = new TableCell(); > > > CELL2 = new TableCell2(); > > > > > > IMG = new Image(); > > > > > > if (_ImageLocation == eAlign.Left){ > > > CELL1.Controls.Add(oImg);CELL2.Controls.Add(new > > > LiteralControl(_HeaderText)); > > > }else{ > > > CELL2.Controls.Add(oImg);CELL1.Controls.Add(new > > > LiteralControl(_HeaderText)); > > > } > > > //etc... > > > } > > > > > > > > > > > > With the above scenario, I have several questions: > > > > > > a) This would work if the control is the public properties were set in > the > > > IDE via HTML, because the Public 'Align' property would be set BEFORE > the > > > CreateControls was called -- the page lifecyle would be > > > * Set Private Fields > > > * Constructor > > > * Set Public Properties from the HTML -- ie the Align > > > * Init > > > * CreateChildControls. > > > > > > But this would fail if mucked around with via code, such as this on the > > page > > > that instantiates the controls > > > * MyControl oC = new MyControl(); > > > * Page.Controls.Add(oC); //Triggers Init, OnLoad, and therefore > > > CreateChildControls...the shape is using the default align=left... > > > * oC.ImageLocation = eAlign.Right; > > > * Result: WRONG LAYOUT!!!! (Still Left instead of new Right). > > > > > > > > > The obvious answer I will probably get is ('don't set public properties > > once > > > added to the page')....But there are times when this is required...plus, > I > > > don't see anywhere in the books where it was stated that Controls, once > > > added to the page, should not be touched. Seems to not be so 'dynamic' > if > > > that is the case... > > > > > > One way I've seen mentioned is to ...Rebuild everything...YIKES!: > > > Public eAlign ImageLocation {get {_ImageLocation;}set > > > {Controls.Clear()ChildControlsCreated=false; and > > re-EnsureChildControls().}} > > > This seems to be completly nutty...build a tree, to throw it away, and > > start > > > again... > > > > > > > > > > > > > > > > > > So... > > > A work around seems to break the rendering into two parts: use the > > > CreateChildControls to create all the necessary components -- but not > > finish > > > the Tree until the PreRender stage: > > > > > > CreateChildControls { > > > oTable = new Table();this.Controls.Add(oTable); > > > ROW = new TableRow(); > > > oTable.Rows.Add(oRow); > > > CELL1 = new TableCell(); > > > CELL2 = new TableCell2(); > > > > > > IMG = new Image(); > > > //STOP HERE!!! NEXT PART IS DONE ONLY IN PAGE_PRERENDER LATER > > > } > > > > > > Page_PreRender(){ > > > if (_ImageLocation == eAlign.Left){ > > > oCell1.Controls.Add(oImg);oCell2.Controls.Add(new > > > LiteralControl(_HeaderText)); > > > }else{ > > > oCell2.Controls.Add(oImg);oCell1.Controls.Add(new > > > LiteralControl(_HeaderText)); > > > } > > > //Good place to apply any custom styling too... > > > } > > > > > > > > > But NONE of the books seem to use the PreRender event -- in fact, it > > almost > > > looks like they steer away from it...Any reason why? > > > > > > > > > > > > > > > > > > Finally -- one last dumb question. I see a lot of > Examples/books/articles > > > stating that all get/set properties talking directly to a sub element > > should > > > have EnsureChildControls in front of it: > > > > > > string Text {get {EnsureChildControls();return _TEXTBOX.Text;} set > > > {EnsureChildControls();_TEXTBOX.Text=value}} > > > > > > Ok...maybe this is just me...but We're talking about using a function > > jump, > > > which checks a boolean property get function which covers a private > > > field...for EVERY public property that is set....Isn't this overkill???? > > > Would it not be better to get this work out of the way as soon as > > possible, > > > once, and to not have to call EnsureChildControls() all the time? > > > How about doing it at the earliest possible time -- in the Constructor: > > > > > > MyControl : WebControl{ > > > //Constructor > > > MyControl():base(){ > > > //Private Fields have been intialized already > > > //but no public properties have been called yet, so it's the right > > time > > > to do this: > > > EnsureChildControls(); > > > } > > > ..... > > > > > > } > > > > > > > > > My question: I get worried when I see that i am the only person doing > > > something ;-)....and I can't find a single person who is using > > > EnsureChildControls() in the constructor.... Is there any practical > reason > > > that it is too early? > > > I know that I they won't be rehydrated yet, until the Page_Load(), but > > > that's ok. I just need to be able to get rid of EnsureChildControls() > > being > > > everywhere. > > > > > > > > > > > > > > > > > > Thank you kindly for any advice you may have on how find the 'perfect' > > > recipie for building custom controls... ;-) > > > Sky > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
Re: question about LifeCycle for controls that change the 'shape' of their control tree?
Hi Robert -- and again, thanks for the feedback :-) (When you work in a
vacuum like I, every feedback about how others are trying to solve things is mana from heaven!) A: You said: "I once tried to do the same thing, but eventualy gave up, because I work in a multi developer environment and it would probably confuse others that would be (maybe) reediting my custom control." That was one of the reasons of asking the question...one of these days I will have to take this skill and work with others, so I musn't stray too far from the flock ;-) The only question that remains of course was, after having considered this approach, but having to work with others, WHAT methodology did you end up working with as a solution to the two step process? I agree that most controls don't change their layout -- and therefore making the subcontrols, and placing them can be all done in CreateChildControls() -- but I am still really confused as what to do about Styles...-- I still see no good time to apply them! If I apply them at CreateChildControls() it's too early and changes via code can happen later, if I apply them in Render() too late, and PreRender() we both agree is a good time -- but not to use it too often as it is not 'common practice' when working in a team. So when do YOU apply styles??? I saw the overrideable methods that are specifically for applyStyles inline during the Render stage -- but that looks more appropriate for controls that are made from scratch -- not Composite Controls. The question is also relevant of course because creating Designers for every control is a very time consuming process -- the more often I can use a GenericDesigner would be nice :-) What are you guys doing? Designing custom desginers for everything? Or not? B: As for CreateChildControls being called even if not called by code within a custom control -- yes, I had noticed that...and thought that this was being called by the page or someother control, as you suggested... But I think I was very wary of it due to microsoft stating that it's time of being called was indeterminant... ie could happen at any time. Hence my trying to get it out of the way at a Determinant way, as early as possible.... (Addendum: on the page you mentioned it says: "The CreateChildControls method is not listed in the table because it is called whenever the ASP.NET page framework needs to create the controls tree and this method call is not limited to a specific phase in a control's lifecycle. For example, CreateChildControls can be invoked when loading a page, during data binding, or during rendering."... ) C. And to add another twist to the thread... talking about Designers. been looking at trying to make an Editable webcontrol -- actually a collapsible Expand/Collapse panel (aka XP panel) but be editable in the ide. For a couple of nights I stumbled around trying to figure out what was wrong...and finally found out about the ReadWriteDesigner... (or PanelDesigner)...but was terribly disappointed that it doesn't contain a GenEditTimeHtml() (sorry if I am not using the right names for the methods, but I don't have my ide open, and have a terrible memory :-) But I hope you know which method I am referring to) and that its appearance in the ide is a plain IDE -- no possiblity of making it an editable custom looking panel. Between the two (a normal default ControlDesigner that can show the custom borders and headers and icons, but not parse/make visible the contained controls till run time), and a PanelEditor (which can show the contents but not the border, etc until runtime)...I was wondering if I have overlooked something. another designer? Another way? Any knowledge/advice on this? D. And one last question. and totally off the original thread, but on my mind a lot these days... As I said, I am developing this app in a vacuum (stuck temporarily in France due to non-work issues -- with no contemporaries to talk to in English) so have no idea how other shops are working with ASP.NET...It seems to me that Server Controls compiled as Dll's are...more time consuming, but a lot more reusable. Yet I think I see a lot more ASCX/User Controls out there. What is your shop doing? Quick dev in Ascx, then converting to server controls? What do you think most people are doing? Over here in France, there is a huge drive/prefererance for non-US controlled technologies...such as PHP...so most of the magazines are focusing on that. What do you think is the flavour of the month in the US? Is PHP growing due to people being thrown by the huge paradym shift that ASP.NET is? Or is it gaining traction in small shops as well as big shops? (I know that ASP.NET is already being used by huge firms -- but the everyday webshop/small 10-20 person firms in the us are goind towards what?) I know that whatever you may say is just an opinion, but frankly, any opinion other than just my own these days, would be great ;-) Very best, Sky "Robert Koritnik" <robert.koritnik.removethis@avtenta.si> wrote in message news:Ox5ZOoAYEHA.2908@TK2MSFTNGP10.phx.gbl... > About two step WebControl creation is a smart thing. Actually I had the same > thing in mind once. First you have to create those controls that will be in > question when ProcessViewState phase begins. That's what you wanted to do. > The second part in PreRender should position those already created controls > into new containers. Seem reasonable. I once tried to do the same thing, but > eventualy gave up, because I work in a multi developer environment and it > would probably confuse others that would be (maybe) reediting my custom > control. > > there's also a great article on ViewState, which also covers some of the > very interesting part of the control's lifecycle: > http://msdn.microsoft.com/library/de...nlifecycle.asp > > The other thing about ChildControlsCreated is somewhere else I think. I also > saw, that EnsureChildControls gets executed even if you don't Create them > and set childcontrolscreated to true. To me it looked more like (not like > your get { checking two conditions}) checking the private bool and if false > calling ensureChildControls and thus making it true. Because I did something > like that. I created CreateChildControls, but I didn't call it in any method > or property set/get. But in the end my webcontrol got created WITH > CreateChildControls method. Looks like that a Page object before responding > back (probably just before SaveViewState) calls EnsureChildControls > recursively over all its containing controls. > > -- > RobertK > { Clever? No just smart. } > > > "Sky" <forums@xact-solutions.removethis.com> wrote in message > news:uaMdU3#XEHA.3120@TK2MSFTNGP12.phx.gbl... > > Robert -- thanks for your response ;-) > > Yes -- I did know about the EnsureChildControls() combo with the > > ChildControls Created bool... > > Which by the way seems to do more than just cover up a private bool -- I > > noticed that if I CreateChildControls, and not set > > ChildControlsCreatedExplicitly, and not call base.CreateChildControls(), > the > > ChildControlsCreated is set automatically (!!!). How, where, I don't > know... > > Maybe the code behind ChildControlsCreated looks something like > > > > get { return (_ChildControlsCreated)||(this.Controls.Count>0);} > > > > That aside, it still means that everytime EnsureChildControls is used in a > > property get/set, one is adding a lot of jumping around and checking, for > > something, that in my mind, should already have been taken care of... What > i > > mean is that the code that is happening is something like: > > > > string MyProp(){ > > get { > > EnsureChildControls(); > > //which does > > * jump to addr of EnsureChildControls() > > * if > ((ChildControlsCreated)||this.Controls.Count>0)){r eturn > > true;}else{CreateChildControls();} > > //back to your code: > > //etc. > > } > > } > > In other words -- its still atleast one addr jump, with all that the > > Stack/Reflection stuff of C# does... -- a conditional, a possible iterator > > creation, a count, then return... > > > > Now, I know that I am really being a pain in the bum asking about a realy > > small little waste of bytes -- but I am asking for the sake of getting a > > good grip on the life-cycle -- because as far as I can tell , 3 books = 3 > > different understandings !.... It seems that there is a lot of confusion > > out there about how to make a webcontrol be as flexible as a form > control... > > Or..which is what I suspect -- it's not the books, it's me who is > > confused -- hence the questions ;-) > > > > > > PS: What were your thoughts as to what I am doing about breaking up the > > rendering into two parts (CreateChildControls/PreRender)? I'm working out > > here alone at home and have little contact with other asp.net programmers, > > so most of my methodology is home - brew...And sometimes, it gets so hard > to > > do something, that I start wondering if I am totally looking at the whole > > thing from the wrong angle .... > > > > Very best, > > Sky > > > > > > > > > > > > "Robert Koritnik" <robert.koritnik.removethis@avtenta.si> wrote in message > > news:OxRf8S0XEHA.808@tk2msftngp13.phx.gbl... > > > Your thinking is great but remember there is another property called > > > ChildControlsCreated, which you should set to true in your > > > CreateChildControls at the end. So consecutive calls to > > EnsureChildControls > > > won't actually rebuild the control tree. > > > > > > EnsureChildControls is a method that just checks that control tree is > > > created. And it checks the above boolean property. So whenever you do > > > something on the control (set/get some property that should access any > > > control within the tree), you should call EnsureChildControls() method. > > > > > > Actually when page is rendering it also calls EnsureChildControls > > > recursively on it's controls. So all controls are valid before rendering > > and > > > before the response is sent to the client all controls have a true value > > in > > > childcontrolscreated property. > > > > > > -- > > > RobertK > > > { Clever? No just smart. } > > > > > > "Sky" <forums@xact-solutions.removethis.com> wrote in message > > > news:OjbHOspXEHA.1000@TK2MSFTNGP12.phx.gbl... > > > > Hello: > > > > > > > > All the books I have looked at about how to design custom composite > > server > > > > controls talk about the LifeCycle..and although most is quite clear, > > there > > > > is one nagging type of control creation that I am looking for > > > clarification > > > > about...Can anyone help? > > > > > > > > The following example is a trivial one, but shows the point hopefully > > > > clearly: It's a Table of two cells, that has an ImageLocation property > > > which > > > > determines if the layout should be flipped (image on left, text on > > right): > > > > > > > > CustomHeader():WebControl{ > > > > //Protected Elements > > > > HtmlRow ROW; > > > > HtmlCell CELL1; > > > > HtmlCell CELL2; > > > > Label HEADER; > > > > Image LOGO > > > > > > > > //Private fields: > > > > string _HeaderText; > > > > string _ImgUrl; > > > > eAlign _ImageLocation = eAlign.Right; > > > > > > > > //Public Properties to access Private Fields: > > > > string HeaderText {get {return _HeaderText;}set{_HeaderText;}} > > > > //etc..... > > > > > > > > //Constructor > > > > CustomHeader():base{} > > > > > > > > Init (){ > > > > EnsureCreateControls(); > > > > } > > > > > > > > //LifeCycle > > > > CreateChildControls { > > > > oTable = new Table(); > > > > ROW = new TableRow(); > > > > oTable.Rows.Add(oRow); > > > > CELL1 = new TableCell(); > > > > CELL2 = new TableCell2(); > > > > > > > > IMG = new Image(); > > > > > > > > if (_ImageLocation == eAlign.Left){ > > > > CELL1.Controls.Add(oImg);CELL2.Controls.Add(new > > > > LiteralControl(_HeaderText)); > > > > }else{ > > > > CELL2.Controls.Add(oImg);CELL1.Controls.Add(new > > > > LiteralControl(_HeaderText)); > > > > } > > > > //etc... > > > > } > > > > > > > > > > > > > > > > With the above scenario, I have several questions: > > > > > > > > a) This would work if the control is the public properties were set in > > the > > > > IDE via HTML, because the Public 'Align' property would be set BEFORE > > the > > > > CreateControls was called -- the page lifecyle would be > > > > * Set Private Fields > > > > * Constructor > > > > * Set Public Properties from the HTML -- ie the Align > > > > * Init > > > > * CreateChildControls. > > > > > > > > But this would fail if mucked around with via code, such as this on > the > > > page > > > > that instantiates the controls > > > > * MyControl oC = new MyControl(); > > > > * Page.Controls.Add(oC); //Triggers Init, OnLoad, and therefore > > > > CreateChildControls...the shape is using the default align=left... > > > > * oC.ImageLocation = eAlign.Right; > > > > * Result: WRONG LAYOUT!!!! (Still Left instead of new Right). > > > > > > > > > > > > The obvious answer I will probably get is ('don't set public > properties > > > once > > > > added to the page')....But there are times when this is > required...plus, > > I > > > > don't see anywhere in the books where it was stated that Controls, > once > > > > added to the page, should not be touched. Seems to not be so 'dynamic' > > if > > > > that is the case... > > > > > > > > One way I've seen mentioned is to ...Rebuild everything...YIKES!: > > > > Public eAlign ImageLocation {get {_ImageLocation;}set > > > > {Controls.Clear()ChildControlsCreated=false; and > > > re-EnsureChildControls().}} > > > > This seems to be completly nutty...build a tree, to throw it away, and > > > start > > > > again... > > > > > > > > > > > > > > > > > > > > > > > > So... > > > > A work around seems to break the rendering into two parts: use the > > > > CreateChildControls to create all the necessary components -- but not > > > finish > > > > the Tree until the PreRender stage: > > > > > > > > CreateChildControls { > > > > oTable = new Table();this.Controls.Add(oTable); > > > > ROW = new TableRow(); > > > > oTable.Rows.Add(oRow); > > > > CELL1 = new TableCell(); > > > > CELL2 = new TableCell2(); > > > > > > > > IMG = new Image(); > > > > //STOP HERE!!! NEXT PART IS DONE ONLY IN PAGE_PRERENDER LATER > > > > } > > > > > > > > Page_PreRender(){ > > > > if (_ImageLocation == eAlign.Left){ > > > > oCell1.Controls.Add(oImg);oCell2.Controls.Add(new > > > > LiteralControl(_HeaderText)); > > > > }else{ > > > > oCell2.Controls.Add(oImg);oCell1.Controls.Add(new > > > > LiteralControl(_HeaderText)); > > > > } > > > > //Good place to apply any custom styling too... > > > > } > > > > > > > > > > > > But NONE of the books seem to use the PreRender event -- in fact, it > > > almost > > > > looks like they steer away from it...Any reason why? > > > > > > > > > > > > > > > > > > > > > > > > Finally -- one last dumb question. I see a lot of > > Examples/books/articles > > > > stating that all get/set properties talking directly to a sub element > > > should > > > > have EnsureChildControls in front of it: > > > > > > > > string Text {get {EnsureChildControls();return _TEXTBOX.Text;} set > > > > {EnsureChildControls();_TEXTBOX.Text=value}} > > > > > > > > Ok...maybe this is just me...but We're talking about using a function > > > jump, > > > > which checks a boolean property get function which covers a private > > > > field...for EVERY public property that is set....Isn't this > overkill???? > > > > Would it not be better to get this work out of the way as soon as > > > possible, > > > > once, and to not have to call EnsureChildControls() all the time? > > > > How about doing it at the earliest possible time -- in the > Constructor: > > > > > > > > MyControl : WebControl{ > > > > //Constructor > > > > MyControl():base(){ > > > > //Private Fields have been intialized already > > > > //but no public properties have been called yet, so it's the right > > > time > > > > to do this: > > > > EnsureChildControls(); > > > > } > > > > ..... > > > > > > > > } > > > > > > > > > > > > My question: I get worried when I see that i am the only person doing > > > > something ;-)....and I can't find a single person who is using > > > > EnsureChildControls() in the constructor.... Is there any practical > > reason > > > > that it is too early? > > > > I know that I they won't be rehydrated yet, until the Page_Load(), but > > > > that's ok. I just need to be able to get rid of EnsureChildControls() > > > being > > > > everywhere. > > > > > > > > > > > > > > > > > > > > > > > > Thank you kindly for any advice you may have on how find the 'perfect' > > > > recipie for building custom controls... ;-) > > > > Sky > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
Re: question about LifeCycle for controls that change the 'shape' of their control tree?
(I posted this 2 days ago...but its only now that I see that somehow Outlook
didn't send it out? Anyway --second try) Hi Robert -- and again, thanks for the feedback :-) (When you work in a vacuum like I, every feedback about how others are trying to solve things is mana from heaven!) A: You said: "I once tried to do the same thing, but eventualy gave up, because I work in a multi developer environment and it would probably confuse others that would be (maybe) reediting my custom control." That was one of the reasons of asking the question...one of these days I will have to take this skill and work with others, so I musn't stray too far from the flock ;-) The only question that remains of course was, after having considered this approach, but having to work with others, WHAT methodology did you end up working with as a solution to the two step process? Is the obvious answer you have stopped fighting upstream and are using EnsureChildControls() everywhere? That said, I agree that most controls don't change their layout -- and therefore making the subcontrols, and placing them can be all done in CreateChildControls() -- but I am still really confused as what to do about Styles...-- I still see no good time to apply them! If I apply them at CreateChildControls() it's too early and changes via code can happen later, if I apply them in Render() too late, and PreRender() we both agree is a good time -- but not to use it too often as it is not 'common practice' when working in a team. So when do YOU apply styles??? I saw the overrideable methods that are specifically for applyStyles inline during the Render stage -- but that looks more appropriate for controls that are made from scratch -- not Composite Controls. The question is also relevant of course because creating Designers for every control is a very time consuming process -- the more often I can use a GenericDesigner would be nice :-) What are you guys doing? Designing custom desginers for everything? Or not? B: As for CreateChildControls being called even if not called by code within a custom control -- yes, I had noticed that...and thought that this was being called by the page or someother control, as you suggested... But I think I was very wary of it due to microsoft stating that it's time of being called was indeterminant... ie could happen at any time. Hence my trying to get it out of the way at a Determinant way, as early as possible.... (Addendum: on the page you mentioned it says: "The CreateChildControls method is not listed in the table because it is called whenever the ASP.NET page framework needs to create the controls tree and this method call is not limited to a specific phase in a control's lifecycle. For example, CreateChildControls can be invoked when loading a page, during data binding, or during rendering."... ) C. And to add another twist to the thread... talking about Designers. been looking at trying to make an Editable webcontrol -- actually a collapsible Expand/Collapse panel (aka XP panel) but be editable in the ide. For a couple of nights I stumbled around trying to figure out what was wrong...and finally found out about the ReadWriteDesigner... (or PanelDesigner)...but was terribly disappointed that it doesn't contain a GenEditTimeHtml() (sorry if I am not using the right names for the methods, but I don't have my ide open, and have a terrible memory :-) But I hope you know which method I am referring to) and that its appearance in the ide is a plain looking white box/panel -- no possiblity of making it an editable custom looking panel with header and footer. Between the two (a normal default ControlDesigner that can show the custom borders and headers and icons, but not parse/make visible the contained controls till run time), and a PanelEditor (which can show the contents but not the border, etc until runtime)...I was wondering if I have overlooked something. another designer? Another way? Any knowledge/advice on this? What about TemplateDesigner in such cases? Would this be a workaround? I havn't used templates much so far, so don't know what to use them for/when they are a better way to go. Are they sort of like a UserControl that parsesrawhtml to make the childcontrols? Therefore we're talking about slowing things down by adding parsing? Or? D. And one last question. and totally off the original thread, but on my mind a lot these days... As I said, I am developing this app in a vacuum (stuck temporarily in France due to non-work issues -- with no contemporaries to talk to in English) so have no idea how other shops are working with ASP.NET...It seems to me that Server Controls compiled as Dll's are...more time consuming, but a lot more reusable. Yet I think I see a lot more ASCX/User Controls out there. Is that just because they are easier to post as articles, or because it is what most people are using/working with? What is your shop doing? Quick dev in Ascx, then converting to server controls? Staying with ascx? Not using them? What do you think most people are doing? Over here in France, there is a huge drive/prefererance for non-US controlled technologies...such as PHP...so most of the magazines are focusing on that. What do you think is the flavour of the month in the US? Is PHP growing due to people being thrown by the huge paradym shift that ASP.NET is? Or is it gaining traction in small shops as well as big shops? (I know that ASP.NET is already being used by huge firms -- but the everyday webshop/small 10-20 person firms in the us are goind towards what?) I know that whatever you may say is just an opinion, but frankly, any opinion other than just my own these days, would be great ;-) Very best, Sky "Robert Koritnik" <robert.koritnik.removethis@avtenta.si> wrote in message news:Ox5ZOoAYEHA.2908@TK2MSFTNGP10.phx.gbl... > About two step WebControl creation is a smart thing. Actually I had the same > thing in mind once. First you have to create those controls that will be in > question when ProcessViewState phase begins. That's what you wanted to do. > The second part in PreRender should position those already created controls > into new containers. Seem reasonable. I once tried to do the same thing, but > eventualy gave up, because I work in a multi developer environment and it > would probably confuse others that would be (maybe) reediting my custom > control. > > there's also a great article on ViewState, which also covers some of the > very interesting part of the control's lifecycle: > http://msdn.microsoft.com/library/de...nlifecycle.asp > > The other thing about ChildControlsCreated is somewhere else I think. I also > saw, that EnsureChildControls gets executed even if you don't Create them > and set childcontrolscreated to true. To me it looked more like (not like > your get { checking two conditions}) checking the private bool and if false > calling ensureChildControls and thus making it true. Because I did something > like that. I created CreateChildControls, but I didn't call it in any method > or property set/get. But in the end my webcontrol got created WITH > CreateChildControls method. Looks like that a Page object before responding > back (probably just before SaveViewState) calls EnsureChildControls > recursively over all its containing controls. > > -- > RobertK > { Clever? No just smart. } > > > "Sky" <forums@xact-solutions.removethis.com> wrote in message > news:uaMdU3#XEHA.3120@TK2MSFTNGP12.phx.gbl... > > Robert -- thanks for your response ;-) > > Yes -- I did know about the EnsureChildControls() combo with the > > ChildControls Created bool... > > Which by the way seems to do more than just cover up a private bool -- I > > noticed that if I CreateChildControls, and not set > > ChildControlsCreatedExplicitly, and not call base.CreateChildControls(), > the > > ChildControlsCreated is set automatically (!!!). How, where, I don't > know... > > Maybe the code behind ChildControlsCreated looks something like > > > > get { return (_ChildControlsCreated)||(this.Controls.Count>0);} > > > > That aside, it still means that everytime EnsureChildControls is used in a > > property get/set, one is adding a lot of jumping around and checking, for > > something, that in my mind, should already have been taken care of... What > i > > mean is that the code that is happening is something like: > > > > string MyProp(){ > > get { > > EnsureChildControls(); > > //which does > > * jump to addr of EnsureChildControls() > > * if > ((ChildControlsCreated)||this.Controls.Count>0)){r eturn > > true;}else{CreateChildControls();} > > //back to your code: > > //etc. > > } > > } > > In other words -- its still atleast one addr jump, with all that the > > Stack/Reflection stuff of C# does... -- a conditional, a possible iterator > > creation, a count, then return... > > > > Now, I know that I am really being a pain in the bum asking about a realy > > small little waste of bytes -- but I am asking for the sake of getting a > > good grip on the life-cycle -- because as far as I can tell , 3 books = 3 > > different understandings !.... It seems that there is a lot of confusion > > out there about how to make a webcontrol be as flexible as a form > control... > > Or..which is what I suspect -- it's not the books, it's me who is > > confused -- hence the questions ;-) > > > > > > PS: What were your thoughts as to what I am doing about breaking up the > > rendering into two parts (CreateChildControls/PreRender)? I'm working out > > here alone at home and have little contact with other asp.net programmers, > > so most of my methodology is home - brew...And sometimes, it gets so hard > to > > do something, that I start wondering if I am totally looking at the whole > > thing from the wrong angle .... > > > > Very best, > > Sky > > > > > > > > > > > > "Robert Koritnik" <robert.koritnik.removethis@avtenta.si> wrote in message > > news:OxRf8S0XEHA.808@tk2msftngp13.phx.gbl... > > > Your thinking is great but remember there is another property called > > > ChildControlsCreated, which you should set to true in your > > > CreateChildControls at the end. So consecutive calls to > > EnsureChildControls > > > won't actually rebuild the control tree. > > > > > > EnsureChildControls is a method that just checks that control tree is > > > created. And it checks the above boolean property. So whenever you do > > > something on the control (set/get some property that should access any > > > control within the tree), you should call EnsureChildControls() method. > > > > > > Actually when page is rendering it also calls EnsureChildControls > > > recursively on it's controls. So all controls are valid before rendering > > and > > > before the response is sent to the client all controls have a true value > > in > > > childcontrolscreated property. > > > > > > -- > > > RobertK > > > { Clever? No just smart. } > > > > > > "Sky" <forums@xact-solutions.removethis.com> wrote in message > > > news:OjbHOspXEHA.1000@TK2MSFTNGP12.phx.gbl... > > > > Hello: > > > > > > > > All the books I have looked at about how to design custom composite > > server > > > > controls talk about the LifeCycle..and although most is quite clear, > > there > > > > is one nagging type of control creation that I am looking for > > > clarification > > > > about...Can anyone help? > > > > > > > > The following example is a trivial one, but shows the point hopefully > > > > clearly: It's a Table of two cells, that has an ImageLocation property > > > which > > > > determines if the layout should be flipped (image on left, text on > > right): > > > > > > > > CustomHeader():WebControl{ > > > > //Protected Elements > > > > HtmlRow ROW; > > > > HtmlCell CELL1; > > > > HtmlCell CELL2; > > > > Label HEADER; > > > > Image LOGO > > > > > > > > //Private fields: > > > > string _HeaderText; > > > > string _ImgUrl; > > > > eAlign _ImageLocation = eAlign.Right; > > > > > > > > //Public Properties to access Private Fields: > > > > string HeaderText {get {return _HeaderText;}set{_HeaderText;}} > > > > //etc..... > > > > > > > > //Constructor > > > > CustomHeader():base{} > > > > > > > > Init (){ > > > > EnsureCreateControls(); > > > > } > > > > > > > > //LifeCycle > > > > CreateChildControls { > > > > oTable = new Table(); > > > > ROW = new TableRow(); > > > > oTable.Rows.Add(oRow); > > > > CELL1 = new TableCell(); > > > > CELL2 = new TableCell2(); > > > > > > > > IMG = new Image(); > > > > > > > > if (_ImageLocation == eAlign.Left){ > > > > CELL1.Controls.Add(oImg);CELL2.Controls.Add(new > > > > LiteralControl(_HeaderText)); > > > > }else{ > > > > CELL2.Controls.Add(oImg);CELL1.Controls.Add(new > > > > LiteralControl(_HeaderText)); > > > > } > > > > //etc... > > > > } > > > > > > > > > > > > > > > > With the above scenario, I have several questions: > > > > > > > > a) This would work if the control is the public properties were set in > > the > > > > IDE via HTML, because the Public 'Align' property would be set BEFORE > > the > > > > CreateControls was called -- the page lifecyle would be > > > > * Set Private Fields > > > > * Constructor > > > > * Set Public Properties from the HTML -- ie the Align > > > > * Init > > > > * CreateChildControls. > > > > > > > > But this would fail if mucked around with via code, such as this on > the > > > page > > > > that instantiates the controls > > > > * MyControl oC = new MyControl(); > > > > * Page.Controls.Add(oC); //Triggers Init, OnLoad, and therefore > > > > CreateChildControls...the shape is using the default align=left... > > > > * oC.ImageLocation = eAlign.Right; > > > > * Result: WRONG LAYOUT!!!! (Still Left instead of new Right). > > > > > > > > > > > > The obvious answer I will probably get is ('don't set public > properties > > > once > > > > added to the page')....But there are times when this is > required...plus, > > I > > > > don't see anywhere in the books where it was stated that Controls, > once > > > > added to the page, should not be touched. Seems to not be so 'dynamic' > > if > > > > that is the case... > > > > > > > > One way I've seen mentioned is to ...Rebuild everything...YIKES!: > > > > Public eAlign ImageLocation {get {_ImageLocation;}set > > > > {Controls.Clear()ChildControlsCreated=false; and > > > re-EnsureChildControls().}} > > > > This seems to be completly nutty...build a tree, to throw it away, and > > > start > > > > again... > > > > > > > > > > > > > > > > > > > > > > > > So... > > > > A work around seems to break the rendering into two parts: use the > > > > CreateChildControls to create all the necessary components -- but not > > > finish > > > > the Tree until the PreRender stage: > > > > > > > > CreateChildControls { > > > > oTable = new Table();this.Controls.Add(oTable); > > > > ROW = new TableRow(); > > > > oTable.Rows.Add(oRow); > > > > CELL1 = new TableCell(); > > > > CELL2 = new TableCell2(); > > > > > > > > IMG = new Image(); > > > > //STOP HERE!!! NEXT PART IS DONE ONLY IN PAGE_PRERENDER LATER > > > > } > > > > > > > > Page_PreRender(){ > > > > if (_ImageLocation == eAlign.Left){ > > > > oCell1.Controls.Add(oImg);oCell2.Controls.Add(new > > > > LiteralControl(_HeaderText)); > > > > }else{ > > > > oCell2.Controls.Add(oImg);oCell1.Controls.Add(new > > > > LiteralControl(_HeaderText)); > > > > } > > > > //Good place to apply any custom styling too... > > > > } > > > > > > > > > > > > But NONE of the books seem to use the PreRender event -- in fact, it > > > almost > > > > looks like they steer away from it...Any reason why? > > > > > > > > > > > > > > > > > > > > > > > > Finally -- one last dumb question. I see a lot of > > Examples/books/articles > > > > stating that all get/set properties talking directly to a sub element > > > should > > > > have EnsureChildControls in front of it: > > > > > > > > string Text {get {EnsureChildControls();return _TEXTBOX.Text;} set > > > > {EnsureChildControls();_TEXTBOX.Text=value}} > > > > > > > > Ok...maybe this is just me...but We're talking about using a function > > > jump, > > > > which checks a boolean property get function which covers a private > > > > field...for EVERY public property that is set....Isn't this > overkill???? > > > > Would it not be better to get this work out of the way as soon as > > > possible, > > > > once, and to not have to call EnsureChildControls() all the time? > > > > How about doing it at the earliest possible time -- in the > Constructor: > > > > > > > > MyControl : WebControl{ > > > > //Constructor > > > > MyControl():base(){ > > > > //Private Fields have been intialized already > > > > //but no public properties have been called yet, so it's the right > > > time > > > > to do this: > > > > EnsureChildControls(); > > > > } > > > > ..... > > > > > > > > } > > > > > > > > > > > > My question: I get worried when I see that i am the only person doing > > > > something ;-)....and I can't find a single person who is using > > > > EnsureChildControls() in the constructor.... Is there any practical > > reason > > > > that it is too early? > > > > I know that I they won't be rehydrated yet, until the Page_Load(), but > > > > that's ok. I just need to be able to get rid of EnsureChildControls() > > > being > > > > everywhere. > > > > > > > > > > > > > > > > > > > > > > > > Thank you kindly for any advice you may have on how find the 'perfect' > > > > recipie for building custom controls... ;-) > > > > Sky > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > "Robert Koritnik" <robert.koritnik.removethis@avtenta.si> wrote in message news:Ox5ZOoAYEHA.2908@TK2MSFTNGP10.phx.gbl... > About two step WebControl creation is a smart thing. Actually I had the same > thing in mind once. First you have to create those controls that will be in > question when ProcessViewState phase begins. That's what you wanted to do. > The second part in PreRender should position those already created controls > into new containers. Seem reasonable. I once tried to do the same thing, but > eventualy gave up, because I work in a multi developer environment and it > would probably confuse others that would be (maybe) reediting my custom > control. > > there's also a great article on ViewState, which also covers some of the > very interesting part of the control's lifecycle: > http://msdn.microsoft.com/library/de...nlifecycle.asp > > The other thing about ChildControlsCreated is somewhere else I think. I also > saw, that EnsureChildControls gets executed even if you don't Create them > and set childcontrolscreated to true. To me it looked more like (not like > your get { checking two conditions}) checking the private bool and if false > calling ensureChildControls and thus making it true. Because I did something > like that. I created CreateChildControls, but I didn't call it in any method > or property set/get. But in the end my webcontrol got created WITH > CreateChildControls method. Looks like that a Page object before responding > back (probably just before SaveViewState) calls EnsureChildControls > recursively over all its containing controls. > > -- > RobertK > { Clever? No just smart. } > > > "Sky" <forums@xact-solutions.removethis.com> wrote in message > news:uaMdU3#XEHA.3120@TK2MSFTNGP12.phx.gbl... > > Robert -- thanks for your response ;-) > > Yes -- I did know about the EnsureChildControls() combo with the > > ChildControls Created bool... > > Which by the way seems to do more than just cover up a private bool -- I > > noticed that if I CreateChildControls, and not set > > ChildControlsCreatedExplicitly, and not call base.CreateChildControls(), > the > > ChildControlsCreated is set automatically (!!!). How, where, I don't > know... > > Maybe the code behind ChildControlsCreated looks something like > > > > get { return (_ChildControlsCreated)||(this.Controls.Count>0);} > > > > That aside, it still means that everytime EnsureChildControls is used in a > > property get/set, one is adding a lot of jumping around and checking, for > > something, that in my mind, should already have been taken care of... What > i > > mean is that the code that is happening is something like: > > > > string MyProp(){ > > get { > > EnsureChildControls(); > > //which does > > * jump to addr of EnsureChildControls() > > * if > ((ChildControlsCreated)||this.Controls.Count>0)){r eturn > > true;}else{CreateChildControls();} > > //back to your code: > > //etc. > > } > > } > > In other words -- its still atleast one addr jump, with all that the > > Stack/Reflection stuff of C# does... -- a conditional, a possible iterator > > creation, a count, then return... > > > > Now, I know that I am really being a pain in the bum asking about a realy > > small little waste of bytes -- but I am asking for the sake of getting a > > good grip on the life-cycle -- because as far as I can tell , 3 books = 3 > > different understandings !.... It seems that there is a lot of confusion > > out there about how to make a webcontrol be as flexible as a form > control... > > Or..which is what I suspect -- it's not the books, it's me who is > > confused -- hence the questions ;-) > > > > > > PS: What were your thoughts as to what I am doing about breaking up the > > rendering into two parts (CreateChildControls/PreRender)? I'm working out > > here alone at home and have little contact with other asp.net programmers, > > so most of my methodology is home - brew...And sometimes, it gets so hard > to > > do something, that I start wondering if I am totally looking at the whole > > thing from the wrong angle .... > > > > Very best, > > Sky > > > > > > > > > > > > "Robert Koritnik" <robert.koritnik.removethis@avtenta.si> wrote in message > > news:OxRf8S0XEHA.808@tk2msftngp13.phx.gbl... > > > Your thinking is great but remember there is another property called > > > ChildControlsCreated, which you should set to true in your > > > CreateChildControls at the end. So consecutive calls to > > EnsureChildControls > > > won't actually rebuild the control tree. > > > > > > EnsureChildControls is a method that just checks that control tree is > > > created. And it checks the above boolean property. So whenever you do > > > something on the control (set/get some property that should access any > > > control within the tree), you should call EnsureChildControls() method. > > > > > > Actually when page is rendering it also calls EnsureChildControls > > > recursively on it's controls. So all controls are valid before rendering > > and > > > before the response is sent to the client all controls have a true value > > in > > > childcontrolscreated property. > > > > > > -- > > > RobertK > > > { Clever? No just smart. } > > > > > > "Sky" <forums@xact-solutions.removethis.com> wrote in message > > > news:OjbHOspXEHA.1000@TK2MSFTNGP12.phx.gbl... > > > > Hello: > > > > > > > > All the books I have looked at about how to design custom composite > > server > > > > controls talk about the LifeCycle..and although most is quite clear, > > there > > > > is one nagging type of control creation that I am looking for > > > clarification > > > > about...Can anyone help? > > > > > > > > The following example is a trivial one, but shows the point hopefully > > > > clearly: It's a Table of two cells, that has an ImageLocation property > > > which > > > > determines if the layout should be flipped (image on left, text on > > right): > > > > > > > > CustomHeader():WebControl{ > > > > //Protected Elements > > > > HtmlRow ROW; > > > > HtmlCell CELL1; > > > > HtmlCell CELL2; > > > > Label HEADER; > > > > Image LOGO > > > > > > > > //Private fields: > > > > string _HeaderText; > > > > string _ImgUrl; > > > > eAlign _ImageLocation = eAlign.Right; > > > > > > > > //Public Properties to access Private Fields: > > > > string HeaderText {get {return _HeaderText;}set{_HeaderText;}} > > > > //etc..... > > > > > > > > //Constructor > > > > CustomHeader():base{} > > > > > > > > Init (){ > > > > EnsureCreateControls(); > > > > } > > > > > > > > //LifeCycle > > > > CreateChildControls { > > > > oTable = new Table(); > > > > ROW = new TableRow(); > > > > oTable.Rows.Add(oRow); > > > > CELL1 = new TableCell(); > > > > CELL2 = new TableCell2(); > > > > > > > > IMG = new Image(); > > > > > > > > if (_ImageLocation == eAlign.Left){ > > > > CELL1.Controls.Add(oImg);CELL2.Controls.Add(new > > > > LiteralControl(_HeaderText)); > > > > }else{ > > > > CELL2.Controls.Add(oImg);CELL1.Controls.Add(new > > > > LiteralControl(_HeaderText)); > > > > } > > > > //etc... > > > > } > > > > > > > > > > > > > > > > With the above scenario, I have several questions: > > > > > > > > a) This would work if the control is the public properties were set in > > the > > > > IDE via HTML, because the Public 'Align' property would be set BEFORE > > the > > > > CreateControls was called -- the page lifecyle would be > > > > * Set Private Fields > > > > * Constructor > > > > * Set Public Properties from the HTML -- ie the Align > > > > * Init > > > > * CreateChildControls. > > > > > > > > But this would fail if mucked around with via code, such as this on > the > > > page > > > > that instantiates the controls > > > > * MyControl oC = new MyControl(); > > > > * Page.Controls.Add(oC); //Triggers Init, OnLoad, and therefore > > > > CreateChildControls...the shape is using the default align=left... > > > > * oC.ImageLocation = eAlign.Right; > > > > * Result: WRONG LAYOUT!!!! (Still Left instead of new Right). > > > > > > > > > > > > The obvious answer I will probably get is ('don't set public > properties > > > once > > > > added to the page')....But there are times when this is > required...plus, > > I > > > > don't see anywhere in the books where it was stated that Controls, > once > > > > added to the page, should not be touched. Seems to not be so 'dynamic' > > if > > > > that is the case... > > > > > > > > One way I've seen mentioned is to ...Rebuild everything...YIKES!: > > > > Public eAlign ImageLocation {get {_ImageLocation;}set > > > > {Controls.Clear()ChildControlsCreated=false; and > > > re-EnsureChildControls().}} > > > > This seems to be completly nutty...build a tree, to throw it away, and > > > start > > > > again... > > > > > > > > > > > > > > > > > > > > > > > > So... > > > > A work around seems to break the rendering into two parts: use the > > > > CreateChildControls to create all the necessary components -- but not > > > finish > > > > the Tree until the PreRender stage: > > > > > > > > CreateChildControls { > > > > oTable = new Table();this.Controls.Add(oTable); > > > > ROW = new TableRow(); > > > > oTable.Rows.Add(oRow); > > > > CELL1 = new TableCell(); > > > > CELL2 = new TableCell2(); > > > > > > > > IMG = new Image(); > > > > //STOP HERE!!! NEXT PART IS DONE ONLY IN PAGE_PRERENDER LATER > > > > } > > > > > > > > Page_PreRender(){ > > > > if (_ImageLocation == eAlign.Left){ > > > > oCell1.Controls.Add(oImg);oCell2.Controls.Add(new > > > > LiteralControl(_HeaderText)); > > > > }else{ > > > > oCell2.Controls.Add(oImg);oCell1.Controls.Add(new > > > > LiteralControl(_HeaderText)); > > > > } > > > > //Good place to apply any custom styling too... > > > > } > > > > > > > > > > > > But NONE of the books seem to use the PreRender event -- in fact, it > > > almost > > > > looks like they steer away from it...Any reason why? > > > > > > > > > > > > > > > > > > > > > > > > Finally -- one last dumb question. I see a lot of > > Examples/books/articles > > > > stating that all get/set properties talking directly to a sub element > > > should > > > > have EnsureChildControls in front of it: > > > > > > > > string Text {get {EnsureChildControls();return _TEXTBOX.Text;} set > > > > {EnsureChildControls();_TEXTBOX.Text=value}} > > > > > > > > Ok...maybe this is just me...but We're talking about using a function > > > jump, > > > > which checks a boolean property get function which covers a private > > > > field...for EVERY public property that is set....Isn't this > overkill???? > > > > Would it not be better to get this work out of the way as soon as > > > possible, > > > > once, and to not have to call EnsureChildControls() all the time? > > > > How about doing it at the earliest possible time -- in the > Constructor: > > > > > > > > MyControl : WebControl{ > > > > //Constructor > > > > MyControl():base(){ > > > > //Private Fields have been intialized already > > > > //but no public properties have been called yet, so it's the right > > > time > > > > to do this: > > > > EnsureChildControls(); > > > > } > > > > ..... > > > > > > > > } > > > > > > > > > > > > My question: I get worried when I see that i am the only person doing > > > > something ;-)....and I can't find a single person who is using > > > > EnsureChildControls() in the constructor.... Is there any practical > > reason > > > > that it is too early? > > > > I know that I they won't be rehydrated yet, until the Page_Load(), but > > > > that's ok. I just need to be able to get rid of EnsureChildControls() > > > being > > > > everywhere. > > > > > > > > > > > > > > > > > > > > > > > > Thank you kindly for any advice you may have on how find the 'perfect' > > > > recipie for building custom controls... ;-) > > > > Sky > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
Re: question about LifeCycle for controls that change the 'shape' of their control tree?
Ad.A
What methodology? Well the normal way. If som eproperty set changes child controls, then you have to recreate the whole control... :( But manytimes you can optimize things so code is still acceptable. I normally set style while creating custom control. if that's in Create child controls or of it is in Render. Whatever. I normally ALWAYS use CreateChildControls. Keeps me thinking I have much more power over the creation. Code can get long, but more understandable and more clean. And what is more important it actually supports different client browsers while you use WebControls that support this. If you use Render and actually write plain HTML, you have to take care of that yourself. Sometimes it's necessary that you create a designer. I once did that with a templated databound custom control and still had some problems with DataSource property. Whatever. But actually the designer pretty good integrated into IDE so the control itself was perfectly editable with different templates... So if you intend to share this control and you know that others will use it in Design mode then maybe you should create a designer to make it look more end-resulting. But the problem here is with styles. You don't have the HttpContext, so using images, and CSS from the web would be stupid. The only thing to remember is to display in a manner that would give some information to the developer-user. Ad.B Indeterminant tie of calling CreateChildControls. That's not tru all over. Well .Net is perfectly deterministic, but the use of this method is dependant on the custom control and it's behavior. YOu can call it whenever you need to and as may times you need to. That's probably why they said is not deterministic. Well all know when the constructor get's called or the OnInit or OnLoad event, but for this method you actually don't exactly know when, because it's not an event handler or anything like it... Ad.C You use Templates when there's a need to use them. Like templates for different elements. That comes into mind especially with databound controls. Ad.D Decision between custom/user controls... Well. Custom controls are fast made and less configurable (normally), Custom controls on te other hand are more time consuming to develop but much much more reusable. If they are well developed. Normally we really do make this decisions. We work on more projects and whenever there's a need to produce a control that should be reused (or has a tendence that it's so general that it will be reused) accross projects we create custom controls. In all other cases we make user controls. Sometimes applications use some specifics and that makes decisions easyjer, because we know things will be harder to reuse. Right now we are developing an app that extensiveli uses Microsoft UIPAB and some special approaches and we know these controls are better used as tailored to this framework than using some general custom controls because development would be more time consuming and someone would have many more thing in mind producing those... Many small companies use non MS tools/technologies just because of cheaper end product. MS means M$. But we are on MS products/platforms for so long that we normally produce everything with MS products/technologies. An myself? I was a while ago a Delphi "fan", but now since C# is out I don't miss it all that much anymore. C# is a very good language and i actually love ASP.Net. As much as I hated ASP, this one i really like. But I'm not the one to judge this. Any grown-up and proved technology can be good. Then it depends on your employer's strategy... Most of the times... -- RobertK { Clever? No just smart. } "Sky" <forums@xact-solutions.removethis.com> wrote in message news:OpEI8I3YEHA.712@TK2MSFTNGP11.phx.gbl... > (I posted this 2 days ago...but its only now that I see that somehow Outlook > didn't send it out? Anyway --second try) > > > Hi Robert -- and again, thanks for the feedback :-) (When you work in a > vacuum like I, every feedback about how others are trying to solve things is > mana from heaven!) > > A: > You said: "I once tried to do the same thing, but > eventualy gave up, because I work in a multi developer environment and it > would probably confuse others that would be (maybe) reediting my custom > control." > > That was one of the reasons of asking the question...one of these days I > will have to take this skill and work with others, so I musn't stray too far > from the flock ;-) > The only question that remains of course was, after having considered this > approach, but having to work with others, WHAT methodology did you end up > working with as a solution to the two step process? > Is the obvious answer you have stopped fighting upstream and are using > EnsureChildControls() everywhere? > > > That said, I agree that most controls don't change their layout -- and > therefore making > the subcontrols, and placing them can be all done in > CreateChildControls() -- but I am still really confused as what to do about > Styles...-- I still see no good time to apply them! If I apply them at > CreateChildControls() it's too early and changes via code can happen later, > if I apply them in Render() too late, and PreRender() we both agree is a > good time -- but not to use it too often as it is not 'common practice' when > working in a team. > So when do YOU apply styles??? I saw the overrideable methods that are > specifically for applyStyles inline during the Render stage -- but that > looks more appropriate for controls that are made from scratch -- not > Composite Controls. > > The question is also relevant of course because creating Designers for every > control is a very time consuming process -- the more often I can use a > GenericDesigner would be nice :-) What are you guys doing? Designing custom > desginers for everything? Or not? > > B: > As for CreateChildControls being called even if not called by code within a > custom control -- yes, I had noticed that...and thought that this was being > called by the page or someother control, as you suggested... But I think I > was very wary of it due to microsoft stating that it's time of being called > was indeterminant... ie could happen at any time. Hence my trying to get it > out of the way at a Determinant way, as early as possible.... > (Addendum: on the page you mentioned it says: "The CreateChildControls > method is not listed in the table because it is called whenever the ASP.NET > page framework needs to create the controls tree and this method call is not > limited to a specific phase in a control's lifecycle. For example, > CreateChildControls can be invoked when loading a page, during data binding, > or during rendering."... ) > > > C. > And to add another twist to the thread... talking about Designers. been > looking at trying to make an Editable webcontrol -- actually a collapsible > Expand/Collapse panel (aka XP panel) but be editable in the ide. For a > couple of nights I stumbled around trying to figure out what was wrong...and > finally found out about the ReadWriteDesigner... (or PanelDesigner)...but > was terribly disappointed that it doesn't contain a GenEditTimeHtml() (sorry > if I am not using the right names for the methods, but I don't have my ide > open, and have a terrible memory :-) But I hope you know which method I am > referring to) and that its appearance in the ide is a plain looking white > box/panel -- no > possiblity of making it an editable custom looking panel with header and > footer. Between the two > (a normal default ControlDesigner that can show the custom borders and > headers and icons, but not parse/make visible the contained controls till > run time), and a PanelEditor (which can show the contents but not the > border, etc until runtime)...I was wondering if I have overlooked something. > another designer? Another way? Any knowledge/advice on this? > What about TemplateDesigner in such cases? Would this be a workaround? I > havn't used templates much so far, so don't know what to use them for/when > they are a better way to go. Are they sort of like a UserControl that > parsesrawhtml to make the childcontrols? Therefore we're talking about > slowing things down by adding parsing? Or? > > > D. And one last question. and totally off the original thread, but on my > mind a lot these days... As I said, I am developing this app in a vacuum > (stuck temporarily in France due to non-work issues -- with no > contemporaries to talk to in English) so have no idea how other shops are > working with ASP.NET...It seems to me that Server Controls compiled as Dll's > are...more time consuming, but a lot more reusable. Yet I think I see a lot > more ASCX/User Controls out there. Is that just because they are easier to > post > as articles, or because it is what most people are using/working with? > What is your shop doing? Quick dev in > Ascx, then converting to server controls? Staying with ascx? Not using > them? > What do you think most people are > doing? Over here in France, there is a huge drive/prefererance for non-US > controlled technologies...such as PHP...so most of the magazines are > focusing on that. What do you think is the flavour of the month in the US? > Is PHP growing due to people being thrown by the huge paradym shift that > ASP.NET is? Or is it gaining traction in small shops as well as big shops? > (I know that ASP.NET is already being used by huge firms -- but the everyday > webshop/small 10-20 person firms in the us are goind towards what?) > I know that whatever you may say is just an opinion, but frankly, any > opinion other than just my own these days, would be great ;-) > > > Very best, > Sky > > > > > > > > > > "Robert Koritnik" <robert.koritnik.removethis@avtenta.si> wrote in message > news:Ox5ZOoAYEHA.2908@TK2MSFTNGP10.phx.gbl... > > About two step WebControl creation is a smart thing. Actually I had the > same > > thing in mind once. First you have to create those controls that will be > in > > question when ProcessViewState phase begins. That's what you wanted to do. > > The second part in PreRender should position those already created > controls > > into new containers. Seem reasonable. I once tried to do the same thing, > but > > eventualy gave up, because I work in a multi developer environment and it > > would probably confuse others that would be (maybe) reediting my custom > > control. > > > > there's also a great article on ViewState, which also covers some of the > > very interesting part of the control's lifecycle: > > > http://msdn.microsoft.com/library/de...nlifecycle.asp > > > > The other thing about ChildControlsCreated is somewhere else I think. I > also > > saw, that EnsureChildControls gets executed even if you don't Create them > > and set childcontrolscreated to true. To me it looked more like (not like > > your get { checking two conditions}) checking the private bool and if > false > > calling ensureChildControls and thus making it true. Because I did > something > > like that. I created CreateChildControls, but I didn't call it in any > method > > or property set/get. But in the end my webcontrol got created WITH > > CreateChildControls method. Looks like that a Page object before > responding > > back (probably just before SaveViewState) calls EnsureChildControls > > recursively over all its containing controls. > > > > -- > > RobertK > > { Clever? No just smart. } > > > > > > "Sky" <forums@xact-solutions.removethis.com> wrote in message > > news:uaMdU3#XEHA.3120@TK2MSFTNGP12.phx.gbl... > > > Robert -- thanks for your response ;-) > > > Yes -- I did know about the EnsureChildControls() combo with the > > > ChildControls Created bool... > > > Which by the way seems to do more than just cover up a private bool -- I > > > noticed that if I CreateChildControls, and not set > > > ChildControlsCreatedExplicitly, and not call base.CreateChildControls(), > > the > > > ChildControlsCreated is set automatically (!!!). How, where, I don't > > know... > > > Maybe the code behind ChildControlsCreated looks something like > > > > > > get { return (_ChildControlsCreated)||(this.Controls.Count>0);} > > > > > > That aside, it still means that everytime EnsureChildControls is used in > a > > > property get/set, one is adding a lot of jumping around and checking, > for > > > something, that in my mind, should already have been taken care of... > What > > i > > > mean is that the code that is happening is something like: > > > > > > string MyProp(){ > > > get { > > > EnsureChildControls(); > > > //which does > > > * jump to addr of EnsureChildControls() > > > * if > > ((ChildControlsCreated)||this.Controls.Count>0)){r eturn > > > true;}else{CreateChildControls();} > > > //back to your code: > > > //etc. > > > } > > > } > > > In other words -- its still atleast one addr jump, with all that the > > > Stack/Reflection stuff of C# does... -- a conditional, a possible > iterator > > > creation, a count, then return... > > > > > > Now, I know that I am really being a pain in the bum asking about a > realy > > > small little waste of bytes -- but I am asking for the sake of getting a > > > good grip on the life-cycle -- because as far as I can tell , 3 books = > 3 > > > different understandings !.... It seems that there is a lot of > confusion > > > out there about how to make a webcontrol be as flexible as a form > > control... > > > Or..which is what I suspect -- it's not the books, it's me who is > > > confused -- hence the questions ;-) > > > > > > > > > PS: What were your thoughts as to what I am doing about breaking up the > > > rendering into two parts (CreateChildControls/PreRender)? I'm working > out > > > here alone at home and have little contact with other asp.net > programmers, > > > so most of my methodology is home - brew...And sometimes, it gets so > hard > > to > > > do something, that I start wondering if I am totally looking at the > whole > > > thing from the wrong angle .... > > > > > > Very best, > > > Sky > > > > > > > > > > > > > > > > > > "Robert Koritnik" <robert.koritnik.removethis@avtenta.si> wrote in > message > > > news:OxRf8S0XEHA.808@tk2msftngp13.phx.gbl... > > > > Your thinking is great but remember there is another property called > > > > ChildControlsCreated, which you should set to true in your > > > > CreateChildControls at the end. So consecutive calls to > > > EnsureChildControls > > > > won't actually rebuild the control tree. > > > > > > > > EnsureChildControls is a method that just checks that control tree is > > > > created. And it checks the above boolean property. So whenever you do > > > > something on the control (set/get some property that should access any > > > > control within the tree), you should call EnsureChildControls() > method. > > > > > > > > Actually when page is rendering it also calls EnsureChildControls > > > > recursively on it's controls. So all controls are valid before > rendering > > > and > > > > before the response is sent to the client all controls have a true > value > > > in > > > > childcontrolscreated property. > > > > > > > > -- > > > > RobertK > > > > { Clever? No just smart. } > > > > > > > > "Sky" <forums@xact-solutions.removethis.com> wrote in message > > > > news:OjbHOspXEHA.1000@TK2MSFTNGP12.phx.gbl... > > > > > Hello: > > > > > > > > > > All the books I have looked at about how to design custom composite > > > server > > > > > controls talk about the LifeCycle..and although most is quite clear, > > > there > > > > > is one nagging type of control creation that I am looking for > > > > clarification > > > > > about...Can anyone help? > > > > > > > > > > The following example is a trivial one, but shows the point > hopefully > > > > > clearly: It's a Table of two cells, that has an ImageLocation > property > > > > which > > > > > determines if the layout should be flipped (image on left, text on > > > right): > > > > > > > > > > CustomHeader():WebControl{ > > > > > //Protected Elements > > > > > HtmlRow ROW; > > > > > HtmlCell CELL1; > > > > > HtmlCell CELL2; > > > > > Label HEADER; > > > > > Image LOGO > > > > > > > > > > //Private fields: > > > > > string _HeaderText; > > > > > string _ImgUrl; > > > > > eAlign _ImageLocation = eAlign.Right; > > > > > > > > > > //Public Properties to access Private Fields: > > > > > string HeaderText {get {return _HeaderText;}set{_HeaderText;}} > > > > > //etc..... > > > > > > > > > > //Constructor > > > > > CustomHeader():base{} > > > > > > > > > > Init (){ > > > > > EnsureCreateControls(); > > > > > } > > > > > > > > > > //LifeCycle > > > > > CreateChildControls { > > > > > oTable = new Table(); > > > > > ROW = new TableRow(); > > > > > oTable.Rows.Add(oRow); > > > > > CELL1 = new TableCell(); > > > > > CELL2 = new TableCell2(); > > > > > > > > > > IMG = new Image(); > > > > > > > > > > if (_ImageLocation == eAlign.Left){ > > > > > CELL1.Controls.Add(oImg);CELL2.Controls.Add(new > > > > > LiteralControl(_HeaderText)); > > > > > }else{ > > > > > CELL2.Controls.Add(oImg);CELL1.Controls.Add(new > > > > > LiteralControl(_HeaderText)); > > > > > } > > > > > //etc... > > > > > } > > > > > > > > > > > > > > > > > > > > With the above scenario, I have several questions: > > > > > > > > > > a) This would work if the control is the public properties were set > in > > > the > > > > > IDE via HTML, because the Public 'Align' property would be set > BEFORE > > > the > > > > > CreateControls was called -- the page lifecyle would be > > > > > * Set Private Fields > > > > > * Constructor > > > > > * Set Public Properties from the HTML -- ie the Align > > > > > * Init > > > > > * CreateChildControls. > > > > > > > > > > But this would fail if mucked around with via code, such as this on > > the > > > > page > > > > > that instantiates the controls > > > > > * MyControl oC = new MyControl(); > > > > > * Page.Controls.Add(oC); //Triggers Init, OnLoad, and therefore > > > > > CreateChildControls...the shape is using the default align=left... > > > > > * oC.ImageLocation = eAlign.Right; > > > > > * Result: WRONG LAYOUT!!!! (Still Left instead of new Right). > > > > > > > > > > > > > > > The obvious answer I will probably get is ('don't set public > > properties > > > > once > > > > > added to the page')....But there are times when this is > > required...plus, > > > I > > > > > don't see anywhere in the books where it was stated that Controls, > > once > > > > > added to the page, should not be touched. Seems to not be so > 'dynamic' > > > if > > > > > that is the case... > > > > > > > > > > One way I've seen mentioned is to ...Rebuild everything...YIKES!: > > > > > Public eAlign ImageLocation {get {_ImageLocation;}set > > > > > {Controls.Clear()ChildControlsCreated=false; and > > > > re-EnsureChildControls().}} > > > > > This seems to be completly nutty...build a tree, to throw it away, > and > > > > start > > > > > again... > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > So... > > > > > A work around seems to break the rendering into two parts: use the > > > > > CreateChildControls to create all the necessary components -- but > not > > > > finish > > > > > the Tree until the PreRender stage: > > > > > > > > > > CreateChildControls { > > > > > oTable = new Table();this.Controls.Add(oTable); > > > > > ROW = new TableRow(); > > > > > oTable.Rows.Add(oRow); > > > > > CELL1 = new TableCell(); > > > > > CELL2 = new TableCell2(); > > > > > > > > > > IMG = new Image(); > > > > > //STOP HERE!!! NEXT PART IS DONE ONLY IN PAGE_PRERENDER > LATER > > > > > } > > > > > > > > > > Page_PreRender(){ > > > > > if (_ImageLocation == eAlign.Left){ > > > > > oCell1.Controls.Add(oImg);oCell2.Controls.Add(new > > > > > LiteralControl(_HeaderText)); > > > > > }else{ > > > > > oCell2.Controls.Add(oImg);oCell1.Controls.Add(new > > > > > LiteralControl(_HeaderText)); > > > > > } > > > > > //Good place to apply any custom styling too... > > > > > } > > > > > > > > > > > > > > > But NONE of the books seem to use the PreRender event -- in fact, it > > > > almost > > > > > looks like they steer away from it...Any reason why? > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Finally -- one last dumb question. I see a lot of > > > Examples/books/articles > > > > > stating that all get/set properties talking directly to a sub > element > > > > should > > > > > have EnsureChildControls in front of it: > > > > > > > > > > string Text {get {EnsureChildControls();return _TEXTBOX.Text;} set > > > > > {EnsureChildControls();_TEXTBOX.Text=value}} > > > > > > > > > > Ok...maybe this is just me...but We're talking about using a > function > > > > jump, > > > > > which checks a boolean property get function which covers a private > > > > > field...for EVERY public property that is set....Isn't this > > overkill???? > > > > > Would it not be better to get this work out of the way as soon as > > > > possible, > > > > > once, and to not have to call EnsureChildControls() all the time? > > > > > How about doing it at the earliest possible time -- in the > > Constructor: > > > > > > > > > > MyControl : WebControl{ > > > > > //Constructor > > > > > MyControl():base(){ > > > > > //Private Fields have been intialized already > > > > > //but no public properties have been called yet, so it's the > right > > > > time > > > > > to do this: > > > > > EnsureChildControls(); > > > > > } > > > > > ..... > > > > > > > > > > } > > > > > > > > > > > > > > > My question: I get worried when I see that i am the only person > doing > > > > > something ;-)....and I can't find a single person who is using > > > > > EnsureChildControls() in the constructor.... Is there any practical > > > reason > > > > > that it is too early? > > > > > I know that I they won't be rehydrated yet, until the Page_Load(), > but > > > > > that's ok. I just need to be able to get rid of > EnsureChildControls() > > > > being > > > > > everywhere. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Thank you kindly for any advice you may have on how find the > 'perfect' > > > > > recipie for building custom controls... ;-) > > > > > Sky > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > "Robert Koritnik" <robert.koritnik.removethis@avtenta.si> wrote in message > news:Ox5ZOoAYEHA.2908@TK2MSFTNGP10.phx.gbl... > > About two step WebControl creation is a smart thing. Actually I had the > same > > thing in mind once. First you have to create those controls that will be > in > > question when ProcessViewState phase begins. That's what you wanted to do. > > The second part in PreRender should position those already created > controls > > into new containers. Seem reasonable. I once tried to do the same thing, > but > > eventualy gave up, because I work in a multi developer environment and it > > would probably confuse others that would be (maybe) reediting my custom > > control. > > > > there's also a great article on ViewState, which also covers some of the > > very interesting part of the control's lifecycle: > > > http://msdn.microsoft.com/library/de...nlifecycle.asp > > > > The other thing about ChildControlsCreated is somewhere else I think. I > also > > saw, that EnsureChildControls gets executed even if you don't Create them > > and set childcontrolscreated to true. To me it looked more like (not like > > your get { checking two conditions}) checking the private bool and if > false > > calling ensureChildControls and thus making it true. Because I did > something > > like that. I created CreateChildControls, but I didn't call it in any > method > > or property set/get. But in the end my webcontrol got created WITH > > CreateChildControls method. Looks like that a Page object before > responding > > back (probably just before SaveViewState) calls EnsureChildControls > > recursively over all its containing controls. > > > > -- > > RobertK > > { Clever? No just smart. } > > > > > > "Sky" <forums@xact-solutions.removethis.com> wrote in message > > news:uaMdU3#XEHA.3120@TK2MSFTNGP12.phx.gbl... > > > Robert -- thanks for your response ;-) > > > Yes -- I did know about the EnsureChildControls() combo with the > > > ChildControls Created bool... > > > Which by the way seems to do more than just cover up a private bool -- I > > > noticed that if I CreateChildControls, and not set > > > ChildControlsCreatedExplicitly, and not call base.CreateChildControls(), > > the > > > ChildControlsCreated is set automatically (!!!). How, where, I don't > > know... > > > Maybe the code behind ChildControlsCreated looks something like > > > > > > get { return (_ChildControlsCreated)||(this.Controls.Count>0);} > > > > > > That aside, it still means that everytime EnsureChildControls is used in > a > > > property get/set, one is adding a lot of jumping around and checking, > for > > > something, that in my mind, should already have been taken care of... > What > > i > > > mean is that the code that is happening is something like: > > > > > > string MyProp(){ > > > get { > > > EnsureChildControls(); > > > //which does > > > * jump to addr of EnsureChildControls() > > > * if > > ((ChildControlsCreated)||this.Controls.Count>0)){r eturn > > > true;}else{CreateChildControls();} > > > //back to your code: > > > //etc. > > > } > > > } > > > In other words -- its still atleast one addr jump, with all that the > > > Stack/Reflection stuff of C# does... -- a conditional, a possible > iterator > > > creation, a count, then return... > > > > > > Now, I know that I am really being a pain in the bum asking about a > realy > > > small little waste of bytes -- but I am asking for the sake of getting a > > > good grip on the life-cycle -- because as far as I can tell , 3 books = > 3 > > > different understandings !.... It seems that there is a lot of > confusion > > > out there about how to make a webcontrol be as flexible as a form > > control... > > > Or..which is what I suspect -- it's not the books, it's me who is > > > confused -- hence the questions ;-) > > > > > > > > > PS: What were your thoughts as to what I am doing about breaking up the > > > rendering into two parts (CreateChildControls/PreRender)? I'm working > out > > > here alone at home and have little contact with other asp.net > programmers, > > > so most of my methodology is home - brew...And sometimes, it gets so > hard > > to > > > do something, that I start wondering if I am totally looking at the > whole > > > thing from the wrong angle .... > > > > > > Very best, > > > Sky > > > > > > > > > > > > > > > > > > "Robert Koritnik" <robert.koritnik.removethis@avtenta.si> wrote in > message > > > news:OxRf8S0XEHA.808@tk2msftngp13.phx.gbl... > > > > Your thinking is great but remember there is another property called > > > > ChildControlsCreated, which you should set to true in your > > > > CreateChildControls at the end. So consecutive calls to > > > EnsureChildControls > > > > won't actually rebuild the control tree. > > > > > > > > EnsureChildControls is a method that just checks that control tree is > > > > created. And it checks the above boolean property. So whenever you do > > > > something on the control (set/get some property that should access any > > > > control within the tree), you should call EnsureChildControls() > method. > > > > > > > > Actually when page is rendering it also calls EnsureChildControls > > > > recursively on it's controls. So all controls are valid before > rendering > > > and > > > > before the response is sent to the client all controls have a true > value > > > in > > > > childcontrolscreated property. > > > > > > > > -- > > > > RobertK > > > > { Clever? No just smart. } > > > > > > > > "Sky" <forums@xact-solutions.removethis.com> wrote in message > > > > news:OjbHOspXEHA.1000@TK2MSFTNGP12.phx.gbl... > > > > > Hello: > > > > > > > > > > All the books I have looked at about how to design custom composite > > > server > > > > > controls talk about the LifeCycle..and although most is quite clear, > > > there > > > > > is one nagging type of control creation that I am looking for > > > > clarification > > > > > about...Can anyone help? > > > > > > > > > > The following example is a trivial one, but shows the point > hopefully > > > > > clearly: It's a Table of two cells, that has an ImageLocation > property > > > > which > > > > > determines if the layout should be flipped (image on left, text on > > > right): > > > > > > > > > > CustomHeader():WebControl{ > > > > > //Protected Elements > > > > > HtmlRow ROW; > > > > > HtmlCell CELL1; > > > > > HtmlCell CELL2; > > > > > Label HEADER; > > > > > Image LOGO > > > > > > > > > > //Private fields: > > > > > string _HeaderText; > > > > > string _ImgUrl; > > > > > eAlign _ImageLocation = eAlign.Right; > > > > > > > > > > //Public Properties to access Private Fields: > > > > > string HeaderText {get {return _HeaderText;}set{_HeaderText;}} > > > > > //etc..... > > > > > > > > > > //Constructor > > > > > CustomHeader():base{} > > > > > > > > > > Init (){ > > > > > EnsureCreateControls(); > > > > > } > > > > > > > > > > //LifeCycle > > > > > CreateChildControls { > > > > > oTable = new Table(); > > > > > ROW = new TableRow(); > > > > > oTable.Rows.Add(oRow); > > > > > CELL1 = new TableCell(); > > > > > CELL2 = new TableCell2(); > > > > > > > > > > IMG = new Image(); > > > > > > > > > > if (_ImageLocation == eAlign.Left){ > > > > > CELL1.Controls.Add(oImg);CELL2.Controls.Add(new > > > > > LiteralControl(_HeaderText)); > > > > > }else{ > > > > > CELL2.Controls.Add(oImg);CELL1.Controls.Add(new > > > > > LiteralControl(_HeaderText)); > > > > > } > > > > > //etc... > > > > > } > > > > > > > > > > > > > > > > > > > > With the above scenario, I have several questions: > > > > > > > > > > a) This would work if the control is the public properties were set > in > > > the > > > > > IDE via HTML, because the Public 'Align' property would be set > BEFORE > > > the > > > > > CreateControls was called -- the page lifecyle would be > > > > > * Set Private Fields > > > > > * Constructor > > > > > * Set Public Properties from the HTML -- ie the Align > > > > > * Init > > > > > * CreateChildControls. > > > > > > > > > > But this would fail if mucked around with via code, such as this on > > the > > > > page > > > > > that instantiates the controls > > > > > * MyControl oC = new MyControl(); > > > > > * Page.Controls.Add(oC); //Triggers Init, OnLoad, and therefore > > > > > CreateChildControls...the shape is using the default align=left... > > > > > * oC.ImageLocation = eAlign.Right; > > > > > * Result: WRONG LAYOUT!!!! (Still Left instead of new Right). > > > > > > > > > > > > > > > The obvious answer I will probably get is ('don't set public > > properties > > > > once > > > > > added to the page')....But there are times when this is > > required...plus, > > > I > > > > > don't see anywhere in the books where it was stated that Controls, > > once > > > > > added to the page, should not be touched. Seems to not be so > 'dynamic' > > > if > > > > > that is the case... > > > > > > > > > > One way I've seen mentioned is to ...Rebuild everything...YIKES!: > > > > > Public eAlign ImageLocation {get {_ImageLocation;}set > > > > > {Controls.Clear()ChildControlsCreated=false; and > > > > re-EnsureChildControls().}} > > > > > This seems to be completly nutty...build a tree, to throw it away, > and > > > > start > > > > > again... > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > So... > > > > > A work around seems to break the rendering into two parts: use the > > > > > CreateChildControls to create all the necessary components -- but > not > > > > finish > > > > > the Tree until the PreRender stage: > > > > > > > > > > CreateChildControls { > > > > > oTable = new Table();this.Controls.Add(oTable); > > > > > ROW = new TableRow(); > > > > > oTable.Rows.Add(oRow); > > > > > CELL1 = new TableCell(); > > > > > CELL2 = new TableCell2(); > > > > > > > > > > IMG = new Image(); > > > > > //STOP HERE!!! NEXT PART IS DONE ONLY IN PAGE_PRERENDER > LATER > > > > > } > > > > > > > > > > Page_PreRender(){ > > > > > if (_ImageLocation == eAlign.Left){ > > > > > oCell1.Controls.Add(oImg);oCell2.Controls.Add(new > > > > > LiteralControl(_HeaderText)); > > > > > }else{ > > > > > oCell2.Controls.Add(oImg);oCell1.Controls.Add(new > > > > > LiteralControl(_HeaderText)); > > > > > } > > > > > //Good place to apply any custom styling too... > > > > > } > > > > > > > > > > > > > > > But NONE of the books seem to use the PreRender event -- in fact, it > > > > almost > > > > > looks like they steer away from it...Any reason why? > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Finally -- one last dumb question. I see a lot of > > > Examples/books/articles > > > > > stating that all get/set properties talking directly to a sub > element > > > > should > > > > > have EnsureChildControls in front of it: > > > > > > > > > > string Text {get {EnsureChildControls();return _TEXTBOX.Text;} set > > > > > {EnsureChildControls();_TEXTBOX.Text=value}} > > > > > > > > > > Ok...maybe this is just me...but We're talking about using a > function > > > > jump, > > > > > which checks a boolean property get function which covers a private > > > > > field...for EVERY public property that is set....Isn't this > > overkill???? > > > > > Would it not be better to get this work out of the way as soon as > > > > possible, > > > > > once, and to not have to call EnsureChildControls() all the time? > > > > > How about doing it at the earliest possible time -- in the > > Constructor: > > > > > > > > > > MyControl : WebControl{ > > > > > //Constructor > > > > > MyControl():base(){ > > > > > //Private Fields have been intialized already > > > > > //but no public properties have been called yet, so it's the > right > > > > time > > > > > to do this: > > > > > EnsureChildControls(); > > > > > } > > > > > ..... > > > > > > > > > > } > > > > > > > > > > > > > > > My question: I get worried when I see that i am the only person > doing > > > > > something ;-)....and I can't find a single person who is using > > > > > EnsureChildControls() in the constructor.... Is there any practical > > > reason > > > > > that it is too early? > > > > > I know that I they won't be rehydrated yet, until the Page_Load(), > but > > > > > that's ok. I just need to be able to get rid of > EnsureChildControls() > > > > being > > > > > everywhere. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Thank you kindly for any advice you may have on how find the > 'perfect' > > > > > recipie for building custom controls... ;-) > > > > > Sky > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
Re: question about LifeCycle for controls that change the 'shape' of their control tree?
Dear Robert:
A. I think we are all on the same page. In other words, a little scoop of CreateChildControls(), a dash of WebControls instead of HtmlControls, a sprinkle of customDesigner/TypeConverters where needed. Fine. Seems I'm going in the right direction ;-) B. Poor choice of word on my part, but I think we both agree as to what it does/when. C....To be discussed in the future .... Templates are a thing/concept that I havn't looked into at all -- concentrating on learning server controls right now. Templates ...next week ;-) D. Delphi was fun .So was C++Builder -- which kicked ass compared to VC++. But happy those days are over. I still think OWL was the best framework -- even better (if less complete) than Net...but it's all so much better than 2 years ago with VB6 etc. I just wish that they had done as good a job with ASP.NET as they did with the rest of the framework. It looks/feels half baked...although I like very much where they are going with Framework 2 though (page events without having to do a secondary fetch -- all done behind the page, I assume by XMLHttp requests?) Anyway.... But one thing I Do NOT like is the speed at which I can produce. :-( WAY too heavy/intense learning curve/special tricks/deep research for the most trivial things... I can do a PHP website in a day -- it takes me a day to do one little control in C#!!! Not right. They are expecting too much from webdesigners in my opinion -- sort of trying to catapult webdesigners up to C++ levels... Too steep....(Rant over -- back to work ;-) Just wanted to say thanks for all your responses ;-) Tonights new research/query in the forums is how to make a Custom ControlBuilder to read nested/nested tags.... Maybe you know the answer to that as well? :-) Very best, Sky "Robert Koritnik" <robert.koritnik.removethis@avtenta.si> wrote in message news:%238QVbHPZEHA.2776@TK2MSFTNGP10.phx.gbl... > Ad.A > What methodology? Well the normal way. If som eproperty set changes child > controls, then you have to recreate the whole control... :( But manytimes > you can optimize things so code is still acceptable. I normally set style > while creating custom control. if that's in Create child controls or of it > is in Render. Whatever. I normally ALWAYS use CreateChildControls. Keeps me > thinking I have much more power over the creation. Code can get long, but > more understandable and more clean. And what is more important it actually > supports different client browsers while you use WebControls that support > this. If you use Render and actually write plain HTML, you have to take care > of that yourself. > > Sometimes it's necessary that you create a designer. I once did that with a > templated databound custom control and still had some problems with > DataSource property. Whatever. But actually the designer pretty good > integrated into IDE so the control itself was perfectly editable with > different templates... > So if you intend to share this control and you know that others will use it > in Design mode then maybe you should create a designer to make it look more > end-resulting. But the problem here is with styles. You don't have the > HttpContext, so using images, and CSS from the web would be stupid. The only > thing to remember is to display in a manner that would give some information > to the developer-user. > > Ad.B > Indeterminant tie of calling CreateChildControls. That's not tru all over. > Well .Net is perfectly deterministic, but the use of this method is > dependant on the custom control and it's behavior. YOu can call it whenever > you need to and as may times you need to. That's probably why they said is > not deterministic. Well all know when the constructor get's called or the > OnInit or OnLoad event, but for this method you actually don't exactly know > when, because it's not an event handler or anything like it... > > Ad.C > You use Templates when there's a need to use them. Like templates for > different elements. That comes into mind especially with databound controls. > > Ad.D > Decision between custom/user controls... Well. Custom controls are fast made > and less configurable (normally), Custom controls on te other hand are more > time consuming to develop but much much more reusable. If they are well > developed. Normally we really do make this decisions. We work on more > projects and whenever there's a need to produce a control that should be > reused (or has a tendence that it's so general that it will be reused) > accross projects we create custom controls. In all other cases we make user > controls. Sometimes applications use some specifics and that makes decisions > easyjer, because we know things will be harder to reuse. Right now we are > developing an app that extensiveli uses Microsoft UIPAB and some special > approaches and we know these controls are better used as tailored to this > framework than using some general custom controls because development would > be more time consuming and someone would have many more thing in mind > producing those... > > Many small companies use non MS tools/technologies just because of cheaper > end product. MS means M$. But we are on MS products/platforms for so long > that we normally produce everything with MS products/technologies. An > myself? I was a while ago a Delphi "fan", but now since C# is out I don't > miss it all that much anymore. C# is a very good language and i actually > love ASP.Net. As much as I hated ASP, this one i really like. But I'm not > the one to judge this. Any grown-up and proved technology can be good. Then > it depends on your employer's strategy... Most of the times... > > -- > RobertK > { Clever? No just smart. } > > "Sky" <forums@xact-solutions.removethis.com> wrote in message > news:OpEI8I3YEHA.712@TK2MSFTNGP11.phx.gbl... > > (I posted this 2 days ago...but its only now that I see that somehow > Outlook > > didn't send it out? Anyway --second try) > > > > > > Hi Robert -- and again, thanks for the feedback :-) (When you work in a > > vacuum like I, every feedback about how others are trying to solve things > is > > mana from heaven!) > > > > A: > > You said: "I once tried to do the same thing, but > > eventualy gave up, because I work in a multi developer environment and it > > would probably confuse others that would be (maybe) reediting my custom > > control." > > > > That was one of the reasons of asking the question...one of these days I > > will have to take this skill and work with others, so I musn't stray too > far > > from the flock ;-) > > The only question that remains of course was, after having considered this > > approach, but having to work with others, WHAT methodology did you end up > > working with as a solution to the two step process? > > Is the obvious answer you have stopped fighting upstream and are using > > EnsureChildControls() everywhere? > > > > > > That said, I agree that most controls don't change their layout -- and > > therefore making > > the subcontrols, and placing them can be all done in > > CreateChildControls() -- but I am still really confused as what to do > about > > Styles...-- I still see no good time to apply them! If I apply them at > > CreateChildControls() it's too early and changes via code can happen > later, > > if I apply them in Render() too late, and PreRender() we both agree is a > > good time -- but not to use it too often as it is not 'common practice' > when > > working in a team. > > So when do YOU apply styles??? I saw the overrideable methods that are > > specifically for applyStyles inline during the Render stage -- but that > > looks more appropriate for controls that are made from scratch -- not > > Composite Controls. > > > > The question is also relevant of course because creating Designers for > every > > control is a very time consuming process -- the more often I can use a > > GenericDesigner would be nice :-) What are you guys doing? Designing > custom > > desginers for everything? Or not? > > > > B: > > As for CreateChildControls being called even if not called by code within > a > > custom control -- yes, I had noticed that...and thought that this was > being > > called by the page or someother control, as you suggested... But I think I > > was very wary of it due to microsoft stating that it's time of being > called > > was indeterminant... ie could happen at any time. Hence my trying to get > it > > out of the way at a Determinant way, as early as possible.... > > (Addendum: on the page you mentioned it says: "The CreateChildControls > > method is not listed in the table because it is called whenever the > ASP.NET > > page framework needs to create the controls tree and this method call is > not > > limited to a specific phase in a control's lifecycle. For example, > > CreateChildControls can be invoked when loading a page, during data > binding, > > or during rendering."... ) > > > > > > C. > > And to add another twist to the thread... talking about Designers. been > > looking at trying to make an Editable webcontrol -- actually a collapsible > > Expand/Collapse panel (aka XP panel) but be editable in the ide. For a > > couple of nights I stumbled around trying to figure out what was > wrong...and > > finally found out about the ReadWriteDesigner... (or PanelDesigner)...but > > was terribly disappointed that it doesn't contain a GenEditTimeHtml() > (sorry > > if I am not using the right names for the methods, but I don't have my ide > > open, and have a terrible memory :-) But I hope you know which method I am > > referring to) and that its appearance in the ide is a plain looking white > > box/panel -- no > > possiblity of making it an editable custom looking panel with header and > > footer. Between the two > > (a normal default ControlDesigner that can show the custom borders and > > headers and icons, but not parse/make visible the contained controls till > > run time), and a PanelEditor (which can show the contents but not the > > border, etc until runtime)...I was wondering if I have overlooked > something. > > another designer? Another way? Any knowledge/advice on this? > > What about TemplateDesigner in such cases? Would this be a workaround? I > > havn't used templates much so far, so don't know what to use them for/when > > they are a better way to go. Are they sort of like a UserControl that > > parsesrawhtml to make the childcontrols? Therefore we're talking about > > slowing things down by adding parsing? Or? > > > > > > D. And one last question. and totally off the original thread, but on my > > mind a lot these days... As I said, I am developing this app in a vacuum > > (stuck temporarily in France due to non-work issues -- with no > > contemporaries to talk to in English) so have no idea how other shops are > > working with ASP.NET...It seems to me that Server Controls compiled as > Dll's > > are...more time consuming, but a lot more reusable. Yet I think I see a > lot > > more ASCX/User Controls out there. Is that just because they are easier to > > post > > as articles, or because it is what most people are using/working with? > > What is your shop doing? Quick dev in > > Ascx, then converting to server controls? Staying with ascx? Not using > > them? > > What do you think most people are > > doing? Over here in France, there is a huge drive/prefererance for non-US > > controlled technologies...such as PHP...so most of the magazines are > > focusing on that. What do you think is the flavour of the month in the US? > > Is PHP growing due to people being thrown by the huge paradym shift that > > ASP.NET is? Or is it gaining traction in small shops as well as big shops? > > (I know that ASP.NET is already being used by huge firms -- but the > everyday > > webshop/small 10-20 person firms in the us are goind towards what?) > > I know that whatever you may say is just an opinion, but frankly, any > > opinion other than just my own these days, would be great ;-) > > > > > > Very best, > > Sky > > > > > > > > > > > > > > > > > > > > "Robert Koritnik" <robert.koritnik.removethis@avtenta.si> wrote in message > > news:Ox5ZOoAYEHA.2908@TK2MSFTNGP10.phx.gbl... > > > About two step WebControl creation is a smart thing. Actually I had the > > same > > > thing in mind once. First you have to create those controls that will be > > in > > > question when ProcessViewState phase begins. That's what you wanted to > do. > > > The second part in PreRender should position those already created > > controls > > > into new containers. Seem reasonable. I once tried to do the same thing, > > but > > > eventualy gave up, because I work in a multi developer environment and > it > > > would probably confuse others that would be (maybe) reediting my custom > > > control. > > > > > > there's also a great article on ViewState, which also covers some of the > > > very interesting part of the control's lifecycle: > > > > > > http://msdn.microsoft.com/library/de...nlifecycle.asp > > > > > > The other thing about ChildControlsCreated is somewhere else I think. I > > also > > > saw, that EnsureChildControls gets executed even if you don't Create > them > > > and set childcontrolscreated to true. To me it looked more like (not > like > > > your get { checking two conditions}) checking the private bool and if > > false > > > calling ensureChildControls and thus making it true. Because I did > > something > > > like that. I created CreateChildControls, but I didn't call it in any > > method > > > or property set/get. But in the end my webcontrol got created WITH > > > CreateChildControls method. Looks like that a Page object before > > responding > > > back (probably just before SaveViewState) calls EnsureChildControls > > > recursively over all its containing controls. > > > > > > -- > > > RobertK > > > { Clever? No just smart. } > > > > > > > > > "Sky" <forums@xact-solutions.removethis.com> wrote in message > > > news:uaMdU3#XEHA.3120@TK2MSFTNGP12.phx.gbl... > > > > Robert -- thanks for your response ;-) > > > > Yes -- I did know about the EnsureChildControls() combo with the > > > > ChildControls Created bool... > > > > Which by the way seems to do more than just cover up a private bool -- > I > > > > noticed that if I CreateChildControls, and not set > > > > ChildControlsCreatedExplicitly, and not call > base.CreateChildControls(), > > > the > > > > ChildControlsCreated is set automatically (!!!). How, where, I don't > > > know... > > > > Maybe the code behind ChildControlsCreated looks something like > > > > > > > > get { return (_ChildControlsCreated)||(this.Controls.Count>0);} > > > > > > > > That aside, it still means that everytime EnsureChildControls is used > in > > a > > > > property get/set, one is adding a lot of jumping around and checking, > > for > > > > something, that in my mind, should already have been taken care of... > > What > > > i > > > > mean is that the code that is happening is something like: > > > > > > > > string MyProp(){ > > > > get { > > > > EnsureChildControls(); > > > > //which does > > > > * jump to addr of EnsureChildControls() > > > > * if > > > ((ChildControlsCreated)||this.Controls.Count>0)){r eturn > > > > true;}else{CreateChildControls();} > > > > //back to your code: > > > > //etc. > > > > } > > > > } > > > > In other words -- its still atleast one addr jump, with all that the > > > > Stack/Reflection stuff of C# does... -- a conditional, a possible > > iterator > > > > creation, a count, then return... > > > > > > > > Now, I know that I am really being a pain in the bum asking about a > > realy > > > > small little waste of bytes -- but I am asking for the sake of getting > a > > > > good grip on the life-cycle -- because as far as I can tell , 3 books > = > > 3 > > > > different understandings !.... It seems that there is a lot of > > confusion > > > > out there about how to make a webcontrol be as flexible as a form > > > control... > > > > Or..which is what I suspect -- it's not the books, it's me who is > > > > confused -- hence the questions ;-) > > > > > > > > > > > > PS: What were your thoughts as to what I am doing about breaking up > the > > > > rendering into two parts (CreateChildControls/PreRender)? I'm working > > out > > > > here alone at home and have little contact with other asp.net > > programmers, > > > > so most of my methodology is home - brew...And sometimes, it gets so > > hard > > > to > > > > do something, that I start wondering if I am totally looking at the > > whole > > > > thing from the wrong angle .... > > > > > > > > Very best, > > > > Sky > > > > > > > > > > > > > > > > > > > > > > > > "Robert Koritnik" <robert.koritnik.removethis@avtenta.si> wrote in > > message > > > > news:OxRf8S0XEHA.808@tk2msftngp13.phx.gbl... > > > > > Your thinking is great but remember there is another property called > > > > > ChildControlsCreated, which you should set to true in your > > > > > CreateChildControls at the end. So consecutive calls to > > > > EnsureChildControls > > > > > won't actually rebuild the control tree. > > > > > > > > > > EnsureChildControls is a method that just checks that control tree > is > > > > > created. And it checks the above boolean property. So whenever you > do > > > > > something on the control (set/get some property that should access > any > > > > > control within the tree), you should call EnsureChildControls() > > method. > > > > > > > > > > Actually when page is rendering it also calls EnsureChildControls > > > > > recursively on it's controls. So all controls are valid before > > rendering > > > > and > > > > > before the response is sent to the client all controls have a true > > value > > > > in > > > > > childcontrolscreated property. > > > > > > > > > > -- > > > > > RobertK > > > > > { Clever? No just smart. } > > > > > > > > > > "Sky" <forums@xact-solutions.removethis.com> wrote in message > > > > > news:OjbHOspXEHA.1000@TK2MSFTNGP12.phx.gbl... > > > > > > Hello: > > > > > > > > > > > > All the books I have looked at about how to design custom > composite > > > > server > > > > > > controls talk about the LifeCycle..and although most is quite > clear, > > > > there > > > > > > is one nagging type of control creation that I am looking for > > > > > clarification > > > > > > about...Can anyone help? > > > > > > > > > > > > The following example is a trivial one, but shows the point > > hopefully > > > > > > clearly: It's a Table of two cells, that has an ImageLocation > > property > > > > > which > > > > > > determines if the layout should be flipped (image on left, text on > > > > right): > > > > > > > > > > > > CustomHeader():WebControl{ > > > > > > //Protected Elements > > > > > > HtmlRow ROW; > > > > > > HtmlCell CELL1; > > > > > > HtmlCell CELL2; > > > > > > Label HEADER; > > > > > > Image LOGO > > > > > > > > > > > > //Private fields: > > > > > > string _HeaderText; > > > > > > string _ImgUrl; > > > > > > eAlign _ImageLocation = eAlign.Right; > > > > > > > > > > > > //Public Properties to access Private Fields: > > > > > > string HeaderText {get {return _HeaderText;}set{_HeaderText;}} > > > > > > //etc..... > > > > > > > > > > > > //Constructor > > > > > > CustomHeader():base{} > > > > > > > > > > > > Init (){ > > > > > > EnsureCreateControls(); > > > > > > } > > > > > > > > > > > > //LifeCycle > > > > > > CreateChildControls { > > > > > > oTable = new Table(); > > > > > > ROW = new TableRow(); > > > > > > oTable.Rows.Add(oRow); > > > > > > CELL1 = new TableCell(); > > > > > > CELL2 = new TableCell2(); > > > > > > > > > > > > IMG = new Image(); > > > > > > > > > > > > if (_ImageLocation == eAlign.Left){ > > > > > > CELL1.Controls.Add(oImg);CELL2.Controls.Add(new > > > > > > LiteralControl(_HeaderText)); > > > > > > }else{ > > > > > > CELL2.Controls.Add(oImg);CELL1.Controls.Add(new > > > > > > LiteralControl(_HeaderText)); > > > > > > } > > > > > > //etc... > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > With the above scenario, I have several questions: > > > > > > > > > > > > a) This would work if the control is the public properties were > set > > in > > > > the > > > > > > IDE via HTML, because the Public 'Align' property would be set > > BEFORE > > > > the > > > > > > CreateControls was called -- the page lifecyle would be > > > > > > * Set Private Fields > > > > > > * Constructor > > > > > > * Set Public Properties from the HTML -- ie the Align > > > > > > * Init > > > > > > * CreateChildControls. > > > > > > > > > > > > But this would fail if mucked around with via code, such as this > on > > > the > > > > > page > > > > > > that instantiates the controls > > > > > > * MyControl oC = new MyControl(); > > > > > > * Page.Controls.Add(oC); //Triggers Init, OnLoad, and > therefore > > > > > > CreateChildControls...the shape is using the default align=left... > > > > > > * oC.ImageLocation = eAlign.Right; > > > > > > * Result: WRONG LAYOUT!!!! (Still Left instead of new Right). > > > > > > > > > > > > > > > > > > The obvious answer I will probably get is ('don't set public > > > properties > > > > > once > > > > > > added to the page')....But there are times when this is > > > required...plus, > > > > I > > > > > > don't see anywhere in the books where it was stated that Controls, > > > once > > > > > > added to the page, should not be touched. Seems to not be so > > 'dynamic' > > > > if > > > > > > that is the case... > > > > > > > > > > > > One way I've seen mentioned is to ...Rebuild everything...YIKES!: > > > > > > Public eAlign ImageLocation {get {_ImageLocation;}set > > > > > > {Controls.Clear()ChildControlsCreated=false; and > > > > > re-EnsureChildControls().}} > > > > > > This seems to be completly nutty...build a tree, to throw it away, > > and > > > > > start > > > > > > again... > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > So... > > > > > > A work around seems to break the rendering into two parts: use > the > > > > > > CreateChildControls to create all the necessary components -- but > > not > > > > > finish > > > > > > the Tree until the PreRender stage: > > > > > > > > > > > > CreateChildControls { > > > > > > oTable = new Table();this.Controls.Add(oTable); > > > > > > ROW = new TableRow(); > > > > > > oTable.Rows.Add(oRow); > > > > > > CELL1 = new TableCell(); > > > > > > CELL2 = new TableCell2(); > > > > > > > > > > > > IMG = new Image(); > > > > > > //STOP HERE!!! NEXT PART IS DONE ONLY IN PAGE_PRERENDER > > LATER > > > > > > } > > > > > > > > > > > > Page_PreRender(){ > > > > > > if (_ImageLocation == eAlign.Left){ > > > > > > oCell1.Controls.Add(oImg);oCell2.Controls.Add(new > > > > > > LiteralControl(_HeaderText)); > > > > > > }else{ > > > > > > oCell2.Controls.Add(oImg);oCell1.Controls.Add(new > > > > > > LiteralControl(_HeaderText)); > > > > > > } > > > > > > //Good place to apply any custom styling too... > > > > > > } > > > > > > > > > > > > > > > > > > But NONE of the books seem to use the PreRender event -- in fact, > it > > > > > almost > > > > > > looks like they steer away from it...Any reason why? > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Finally -- one last dumb question. I see a lot of > > > > Examples/books/articles > > > > > > stating that all get/set properties talking directly to a sub > > element > > > > > should > > > > > > have EnsureChildControls in front of it: > > > > > > > > > > > > string Text {get {EnsureChildControls();return _TEXTBOX.Text;} set > > > > > > {EnsureChildControls();_TEXTBOX.Text=value}} > > > > > > > > > > > > Ok...maybe this is just me...but We're talking about using a > > function > > > > > jump, > > > > > > which checks a boolean property get function which covers a > private > > > > > > field...for EVERY public property that is set....Isn't this > > > overkill???? > > > > > > Would it not be better to get this work out of the way as soon as > > > > > possible, > > > > > > once, and to not have to call EnsureChildControls() all the time? > > > > > > How about doing it at the earliest possible time -- in the > > > Constructor: > > > > > > > > > > > > MyControl : WebControl{ > > > > > > //Constructor > > > > > > MyControl():base(){ > > > > > > //Private Fields have been intialized already > > > > > > //but no public properties have been called yet, so it's the > > right > > > > > time > > > > > > to do this: > > > > > > EnsureChildControls(); > > > > > > } > > > > > > ..... > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > My question: I get worried when I see that i am the only person > > doing > > > > > > something ;-)....and I can't find a single person who is using > > > > > > EnsureChildControls() in the constructor.... Is there any > practical > > > > reason > > > > > > that it is too early? > > > > > > I know that I they won't be rehydrated yet, until the Page_Load(), > > but > > > > > > that's ok. I just need to be able to get rid of > > EnsureChildControls() > > > > > being > > > > > > everywhere. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Thank you kindly for any advice you may have on how find the > > 'perfect' > > > > > > recipie for building custom controls... ;-) > > > > > > Sky > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > "Robert Koritnik" <robert.koritnik.removethis@avtenta.si> wrote in message > > news:Ox5ZOoAYEHA.2908@TK2MSFTNGP10.phx.gbl... > > > About two step WebControl creation is a smart thing. Actually I had the > > same > > > thing in mind once. First you have to create those controls that will be > > in > > > question when ProcessViewState phase begins. That's what you wanted to > do. > > > The second part in PreRender should position those already created > > controls > > > into new containers. Seem reasonable. I once tried to do the same thing, > > but > > > eventualy gave up, because I work in a multi developer environment and > it > > > would probably confuse others that would be (maybe) reediting my custom > > > control. > > > > > > there's also a great article on ViewState, which also covers some of the > > > very interesting part of the control's lifecycle: > > > > > > http://msdn.microsoft.com/library/de...nlifecycle.asp > > > > > > The other thing about ChildControlsCreated is somewhere else I think. I > > also > > > saw, that EnsureChildControls gets executed even if you don't Create > them > > > and set childcontrolscreated to true. To me it looked more like (not > like > > > your get { checking two conditions}) checking the private bool and if > > false > > > calling ensureChildControls and thus making it true. Because I did > > something > > > like that. I created CreateChildControls, but I didn't call it in any > > method > > > or property set/get. But in the end my webcontrol got created WITH > > > CreateChildControls method. Looks like that a Page object before > > responding > > > back (probably just before SaveViewState) calls EnsureChildControls > > > recursively over all its containing controls. > > > > > > -- > > > RobertK > > > { Clever? No just smart. } > > > > > > > > > "Sky" <forums@xact-solutions.removethis.com> wrote in message > > > news:uaMdU3#XEHA.3120@TK2MSFTNGP12.phx.gbl... > > > > Robert -- thanks for your response ;-) > > > > Yes -- I did know about the EnsureChildControls() combo with the > > > > ChildControls Created bool... > > > > Which by the way seems to do more than just cover up a private bool -- > I > > > > noticed that if I CreateChildControls, and not set > > > > ChildControlsCreatedExplicitly, and not call > base.CreateChildControls(), > > > the > > > > ChildControlsCreated is set automatically (!!!). How, where, I don't > > > know... > > > > Maybe the code behind ChildControlsCreated looks something like > > > > > > > > get { return (_ChildControlsCreated)||(this.Controls.Count>0);} > > > > > > > > That aside, it still means that everytime EnsureChildControls is used > in > > a > > > > property get/set, one is adding a lot of jumping around and checking, > > for > > > > something, that in my mind, should already have been taken care of... > > What > > > i > > > > mean is that the code that is happening is something like: > > > > > > > > string MyProp(){ > > > > get { > > > > EnsureChildControls(); > > > > //which does > > > > * jump to addr of EnsureChildControls() > > > > * if > > > ((ChildControlsCreated)||this.Controls.Count>0)){r eturn > > > > true;}else{CreateChildControls();} > > > > //back to your code: > > > > //etc. > > > > } > > > > } > > > > In other words -- its still atleast one addr jump, with all that the > > > > Stack/Reflection stuff of C# does... -- a conditional, a possible > > iterator > > > > creation, a count, then return... > > > > > > > > Now, I know that I am really being a pain in the bum asking about a > > realy > > > > small little waste of bytes -- but I am asking for the sake of getting > a > > > > good grip on the life-cycle -- because as far as I can tell , 3 books > = > > 3 > > > > different understandings !.... It seems that there is a lot of > > confusion > > > > out there about how to make a webcontrol be as flexible as a form > > > control... > > > > Or..which is what I suspect -- it's not the books, it's me who is > > > > confused -- hence the questions ;-) > > > > > > > > > > > > PS: What were your thoughts as to what I am doing about breaking up > the > > > > rendering into two parts (CreateChildControls/PreRender)? I'm working > > out > > > > here alone at home and have little contact with other asp.net > > programmers, > > > > so most of my methodology is home - brew...And sometimes, it gets so > > hard > > > to > > > > do something, that I start wondering if I am totally looking at the > > whole > > > > thing from the wrong angle .... > > > > > > > > Very best, > > > > Sky > > > > > > > > > > > > > > > > > > > > > > > > "Robert Koritnik" <robert.koritnik.removethis@avtenta.si> wrote in > > message > > > > news:OxRf8S0XEHA.808@tk2msftngp13.phx.gbl... > > > > > Your thinking is great but remember there is another property called > > > > > ChildControlsCreated, which you should set to true in your > > > > > CreateChildControls at the end. So consecutive calls to > > > > EnsureChildControls > > > > > won't actually rebuild the control tree. > > > > > > > > > > EnsureChildControls is a method that just checks that control tree > is > > > > > created. And it checks the above boolean property. So whenever you > do > > > > > something on the control (set/get some property that should access > any > > > > > control within the tree), you should call EnsureChildControls() > > method. > > > > > > > > > > Actually when page is rendering it also calls EnsureChildControls > > > > > recursively on it's controls. So all controls are valid before > > rendering > > > > and > > > > > before the response is sent to the client all controls have a true > > value > > > > in > > > > > childcontrolscreated property. > > > > > > > > > > -- > > > > > RobertK > > > > > { Clever? No just smart. } > > > > > > > > > > "Sky" <forums@xact-solutions.removethis.com> wrote in message > > > > > news:OjbHOspXEHA.1000@TK2MSFTNGP12.phx.gbl... > > > > > > Hello: > > > > > > > > > > > > All the books I have looked at about how to design custom > composite > > > > server > > > > > > controls talk about the LifeCycle..and although most is quite > clear, > > > > there > > > > > > is one nagging type of control creation that I am looking for > > > > > clarification > > > > > > about...Can anyone help? > > > > > > > > > > > > The following example is a trivial one, but shows the point > > hopefully > > > > > > clearly: It's a Table of two cells, that has an ImageLocation > > property > > > > > which > > > > > > determines if the layout should be flipped (image on left, text on > > > > right): > > > > > > > > > > > > CustomHeader():WebControl{ > > > > > > //Protected Elements > > > > > > HtmlRow ROW; > > > > > > HtmlCell CELL1; > > > > > > HtmlCell CELL2; > > > > > > Label HEADER; > > > > > > Image LOGO > > > > > > > > > > > > //Private fields: > > > > > > string _HeaderText; > > > > > > string _ImgUrl; > > > > > > eAlign _ImageLocation = eAlign.Right; > > > > > > > > > > > > //Public Properties to access Private Fields: > > > > > > string HeaderText {get {return _HeaderText;}set{_HeaderText;}} > > > > > > //etc..... > > > > > > > > > > > > //Constructor > > > > > > CustomHeader():base{} > > > > > > > > > > > > Init (){ > > > > > > EnsureCreateControls(); > > > > > > } > > > > > > > > > > > > //LifeCycle > > > > > > CreateChildControls { > > > > > > oTable = new Table(); > > > > > > ROW = new TableRow(); > > > > > > oTable.Rows.Add(oRow); > > > > > > CELL1 = new TableCell(); > > > > > > CELL2 = new TableCell2(); > > > > > > > > > > > > IMG = new Image(); > > > > > > > > > > > > if (_ImageLocation == eAlign.Left){ > > > > > > CELL1.Controls.Add(oImg);CELL2.Controls.Add(new > > > > > > LiteralControl(_HeaderText)); > > > > > > }else{ > > > > > > CELL2.Controls.Add(oImg);CELL1.Controls.Add(new > > > > > > LiteralControl(_HeaderText)); > > > > > > } > > > > > > //etc... > > > > > > } > > > > > > > > > > > > > > > > > > > > > > > > With the above scenario, I have several questions: > > > > > > > > > > > > a) This would work if the control is the public properties were > set > > in > > > > the > > > > > > IDE via HTML, because the Public 'Align' property would be set > > BEFORE > > > > the > > > > > > CreateControls was called -- the page lifecyle would be > > > > > > * Set Private Fields > > > > > > * Constructor > > > > > > * Set Public Properties from the HTML -- ie the Align > > > > > > * Init > > > > > > * CreateChildControls. > > > > > > > > > > > > But this would fail if mucked around with via code, such as this > on > > > the > > > > > page > > > > > > that instantiates the controls > > > > > > * MyControl oC = new MyControl(); > > > > > > * Page.Controls.Add(oC); //Triggers Init, OnLoad, and > therefore > > > > > > CreateChildControls...the shape is using the default align=left... > > > > > > * oC.ImageLocation = eAlign.Right; > > > > > > * Result: WRONG LAYOUT!!!! (Still Left instead of new Right). > > > > > > > > > > > > > > > > > > The obvious answer I will probably get is ('don't set public > > > properties > > > > > once > > > > > > added to the page')....But there are times when this is > > > required...plus, > > > > I > > > > > > don't see anywhere in the books where it was stated that Controls, > > > once > > > > > > added to the page, should not be touched. Seems to not be so > > 'dynamic' > > > > if > > > > > > that is the case... > > > > > > > > > > > > One way I've seen mentioned is to ...Rebuild everything...YIKES!: > > > > > > Public eAlign ImageLocation {get {_ImageLocation;}set > > > > > > {Controls.Clear()ChildControlsCreated=false; and > > > > > re-EnsureChildControls().}} > > > > > > This seems to be completly nutty...build a tree, to throw it away, > > and > > > > > start > > > > > > again... > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > So... > > > > > > A work around seems to break the rendering into two parts: use > the > > > > > > CreateChildControls to create all the necessary components -- but > > not > > > > > finish > > > > > > the Tree until the PreRender stage: > > > > > > > > > > > > CreateChildControls { > > > > > > oTable = new Table();this.Controls.Add(oTable); > > > > > > ROW = new TableRow(); > > > > > > oTable.Rows.Add(oRow); > > > > > > CELL1 = new TableCell(); > > > > > > CELL2 = new TableCell2(); > > > > > > > > > > > > IMG = new Image(); > > > > > > //STOP HERE!!! NEXT PART IS DONE ONLY IN PAGE_PRERENDER > > LATER > > > > > > } > > > > > > > > > > > > Page_PreRender(){ > > > > > > if (_ImageLocation == eAlign.Left){ > > > > > > oCell1.Controls.Add(oImg);oCell2.Controls.Add(new > > > > > > LiteralControl(_HeaderText)); > > > > > > }else{ > > > > > > oCell2.Controls.Add(oImg);oCell1.Controls.Add(new > > > > > > LiteralControl(_HeaderText)); > > > > > > } > > > > > > //Good place to apply any custom styling too... > > > > > > } > > > > > > > > > > > > > > > > > > But NONE of the books seem to use the PreRender event -- in fact, > it > > > > > almost > > > > > > looks like they steer away from it...Any reason why? > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Finally -- one last dumb question. I see a lot of > > > > Examples/books/articles > > > > > > stating that all get/set properties talking directly to a sub > > element > > > > > should > > > > > > have EnsureChildControls in front of it: > > > > > > > > > > > > string Text {get {EnsureChildControls();return _TEXTBOX.Text;} set > > > > > > {EnsureChildControls();_TEXTBOX.Text=value}} > > > > > > > > > > > > Ok...maybe this is just me...but We're talking about using a > > function > > > > > jump, > > > > > > which checks a boolean property get function which covers a > private > > > > > > field...for EVERY public property that is set....Isn't this > > > overkill???? > > > > > > Would it not be better to get this work out of the way as soon as > > > > > possible, > > > > > > once, and to not have to call EnsureChildControls() all the time? > > > > > > How about doing it at the earliest possible time -- in the > > > Constructor: > > > > > > > > > > > > MyControl : WebControl{ > > > > > > //Constructor > > > > > > MyControl():base(){ > > > > > > //Private Fields have been intialized already > > > > > > //but no public properties have been called yet, so it's the > > right > > > > > time > > > > > > to do this: > > > > > > EnsureChildControls(); > > > > > > } > > > > > > ..... > > > > > > > > > > > > } > > > > > > > > > > > > > > > > > > My question: I get worried when I see that i am the only person > > doing > > > > > > something ;-)....and I can't find a single person who is using > > > > > > EnsureChildControls() in the constructor.... Is there any > practical > > > > reason > > > > > > that it is too early? > > > > > > I know that I they won't be rehydrated yet, until the Page_Load(), > > but > > > > > > that's ok. I just need to be able to get rid of > > EnsureChildControls() > > > > > being > > > > > > everywhere. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > Thank you kindly for any advice you may have on how find the > > 'perfect' > > > > > > recipie for building custom controls... ;-) > > > > > > Sky > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
| All times are GMT. The time now is 10:12 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.