Composite WebControl -- Child Control Property Persistance at Design-time

B

Bob Brunton

Hi,

I seen, this asked a number of times at this group but still have not
seen any complete/rectified/fixed code.

I have created a Composite WebControl, Added a button to it and
exposed this child button as a property. But the properties are not
persisting at design-time. Are the Attributes correct? See Code below.

Now I want to add other controls to this, when/if I get it working. So
simply extending the button control is not a valid solution.

I know the response to this will be greatly appreciated by all those
who have tried but failed, asked but were unanwsered.

Thanks for you replies, If you can get this to work .. great Karma
will come your way.

Regards Nick

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace TestWebControls
{

[
ToolboxData("<{0}:WebCustomControl1
runat=server></{0}:WebCustomControl1>"), PersistChildren(false),
ParseChildren(true)]
public class WebCustomControl1 :
System.Web.UI.WebControls.WebControl, INamingContainer
{

private System.Web.UI.WebControls.TextBox _TextBoxStreet ;//= new
System.Web.UI.WebControls.TextBox();

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public TextBox Street
{
get{
return _TextBoxStreet;
}
}
protected override void OnInit(EventArgs e)
{
EnsureChildControls();
base.OnInit (e);
}

protected override void CreateChildControls()
{
if(_TextBoxStreet == null)
{
_TextBoxStreet = new System.Web.UI.WebControls.TextBox();
this.Controls.Add(_TextBoxStreet);
}
base.CreateChildControls();
}

protected override void Render(HtmlTextWriter output)
{
base.Render(output);
}
}
}
 
B

Bob Brunton

No answer?

If this can't be done then does anyone have a work around?
I thought the dotnet framework could do all. I've followed all the
reference material on webcontrol building and thought this would be
trivial.

If anyone has the answer I will be more than greatfull.

REgards Nick
 
A

Alessandro Zifiglio

Reposting --hope there is no duplicate. I dont see my previous post ;P

hi Bob, you need to use the textbox controls text property in your get/set
accessors and not supply the control as a whole here. Your textbox control
is persisted already when your adding it to your controls collection. The
CreatechildControls method is fired after postback which reloads your
textbox into the controls collection. This is the only prerequisite for
dynamically added controls to persist their state after postback. I've also
noted that you have supplied the
DesignerSerializationVisibility(DesignerSerializationVisibility.Content)
attribute to your Get accessor property which is useless, use this for
complex types only. PersistenceMode(PersistenceMode.InnerDefaultProperty)
also is useless here. all you need to do is :

public string Street
{
get{
EnsureChildControls();
return _TextBoxStreet.Text;
set
{
EnsureChildControls();
_TextBoxStreet.Text = value;
}
}

Also note that child controls maintain their own state, and you dont have to
manually add this to viewstate to have it persist. Make sure you remove the
"if conditional statement" you got in CreateChildControls. All childcontrols
you add to the controls collection have to be recreated and your if
statement breaks this
Bob Brunton said:
No answer?

If this can't be done then does anyone have a work around?
I thought the dotnet framework could do all. I've followed all the
reference material on webcontrol building and thought this would be
trivial.

If anyone has the answer I will be more than greatfull.

REgards Nick



(e-mail address removed) (Bob Brunton) wrote in message
Hi,

I seen, this asked a number of times at this group but still have not
seen any complete/rectified/fixed code.

I have created a Composite WebControl, Added a button to it and
exposed this child button as a property. But the properties are not
persisting at design-time. Are the Attributes correct? See Code below.

Now I want to add other controls to this, when/if I get it working. So
simply extending the button control is not a valid solution.

I know the response to this will be greatly appreciated by all those
who have tried but failed, asked but were unanwsered.

Thanks for you replies, If you can get this to work .. great Karma
will come your way.

Regards Nick

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace TestWebControls
{

[
ToolboxData("<{0}:WebCustomControl1
runat=server></{0}:WebCustomControl1>"), PersistChildren(false),
ParseChildren(true)]
public class WebCustomControl1 :
System.Web.UI.WebControls.WebControl, INamingContainer
{

private System.Web.UI.WebControls.TextBox _TextBoxStreet ;//= new
System.Web.UI.WebControls.TextBox();

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public TextBox Street
{
get{
return _TextBoxStreet;
}
}
protected override void OnInit(EventArgs e)
{
EnsureChildControls();
base.OnInit (e);
}

protected override void CreateChildControls()
{
if(_TextBoxStreet == null)
{
_TextBoxStreet = new System.Web.UI.WebControls.TextBox();
this.Controls.Add(_TextBoxStreet);
}
base.CreateChildControls();
}

protected override void Render(HtmlTextWriter output)
{
base.Render(output);
}
}
}
 
B

Bob Brunton

Thanks for the reply Alessandro,

But I actually want to expose the TextBox as a public property, so I
do need the attributes for this complex type (TextBox). I want more
than just the TextBox Text property.

Nick



Alessandro Zifiglio said:
Reposting --hope there is no duplicate. I dont see my previous post ;P

hi Bob, you need to use the textbox controls text property in your get/set
accessors and not supply the control as a whole here. Your textbox control
is persisted already when your adding it to your controls collection. The
CreatechildControls method is fired after postback which reloads your
textbox into the controls collection. This is the only prerequisite for
dynamically added controls to persist their state after postback. I've also
noted that you have supplied the
DesignerSerializationVisibility(DesignerSerializationVisibility.Content)
attribute to your Get accessor property which is useless, use this for
complex types only. PersistenceMode(PersistenceMode.InnerDefaultProperty)
also is useless here. all you need to do is :

public string Street
{
get{
EnsureChildControls();
return _TextBoxStreet.Text;
set
{
EnsureChildControls();
_TextBoxStreet.Text = value;
}
}

Also note that child controls maintain their own state, and you dont have to
manually add this to viewstate to have it persist. Make sure you remove the
"if conditional statement" you got in CreateChildControls. All childcontrols
you add to the controls collection have to be recreated and your if
statement breaks this
Bob Brunton said:
No answer?

If this can't be done then does anyone have a work around?
I thought the dotnet framework could do all. I've followed all the
reference material on webcontrol building and thought this would be
trivial.

If anyone has the answer I will be more than greatfull.

REgards Nick



(e-mail address removed) (Bob Brunton) wrote in message
Hi,

I seen, this asked a number of times at this group but still have not
seen any complete/rectified/fixed code.

I have created a Composite WebControl, Added a button to it and
exposed this child button as a property. But the properties are not
persisting at design-time. Are the Attributes correct? See Code below.

Now I want to add other controls to this, when/if I get it working. So
simply extending the button control is not a valid solution.

I know the response to this will be greatly appreciated by all those
who have tried but failed, asked but were unanwsered.

Thanks for you replies, If you can get this to work .. great Karma
will come your way.

Regards Nick

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace TestWebControls
{

[
ToolboxData("<{0}:WebCustomControl1
runat=server></{0}:WebCustomControl1>"), PersistChildren(false),
ParseChildren(true)]
public class WebCustomControl1 :
System.Web.UI.WebControls.WebControl, INamingContainer
{

private System.Web.UI.WebControls.TextBox _TextBoxStreet ;//= new
System.Web.UI.WebControls.TextBox();

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public TextBox Street
{
get{
return _TextBoxStreet;
}
}
protected override void OnInit(EventArgs e)
{
EnsureChildControls();
base.OnInit (e);
}

protected override void CreateChildControls()
{
if(_TextBoxStreet == null)
{
_TextBoxStreet = new System.Web.UI.WebControls.TextBox();
this.Controls.Add(_TextBoxStreet);
} base.CreateChildControls();
}

protected override void Render(HtmlTextWriter output)
{
base.Render(output);
}
}
}
 
A

Alessandro Zifiglio

Now i see where you are getting at. Simply trying out your sample code does
not persist the data like you stated. I have tried Customizing State
Restoration with ViewState by overriding saveviewstate, loadviewstate and
trackviewstate but this didnt make a difference. I'll put in some time later
this evening and post how far i were able to get ;P


Bob Brunton said:
Thanks for the reply Alessandro,

But I actually want to expose the TextBox as a public property, so I
do need the attributes for this complex type (TextBox). I want more
than just the TextBox Text property.

Nick



"Alessandro Zifiglio" <[email protected]> wrote in
message news: said:
Reposting --hope there is no duplicate. I dont see my previous post ;P

hi Bob, you need to use the textbox controls text property in your get/set
accessors and not supply the control as a whole here. Your textbox control
is persisted already when your adding it to your controls collection. The
CreatechildControls method is fired after postback which reloads your
textbox into the controls collection. This is the only prerequisite for
dynamically added controls to persist their state after postback. I've also
noted that you have supplied the
DesignerSerializationVisibility(DesignerSerializationVisibility.Content)
attribute to your Get accessor property which is useless, use this for
complex types only. PersistenceMode(PersistenceMode.InnerDefaultProperty)
also is useless here. all you need to do is :

public string Street
{
get{
EnsureChildControls();
return _TextBoxStreet.Text;
set
{
EnsureChildControls();
_TextBoxStreet.Text = value;
}
}

Also note that child controls maintain their own state, and you dont have to
manually add this to viewstate to have it persist. Make sure you remove the
"if conditional statement" you got in CreateChildControls. All childcontrols
you add to the controls collection have to be recreated and your if
statement breaks this
Bob Brunton said:
No answer?

If this can't be done then does anyone have a work around?
I thought the dotnet framework could do all. I've followed all the
reference material on webcontrol building and thought this would be
trivial.

If anyone has the answer I will be more than greatfull.

REgards Nick



(e-mail address removed) (Bob Brunton) wrote in message
Hi,

I seen, this asked a number of times at this group but still have not
seen any complete/rectified/fixed code.

I have created a Composite WebControl, Added a button to it and
exposed this child button as a property. But the properties are not
persisting at design-time. Are the Attributes correct? See Code below.

Now I want to add other controls to this, when/if I get it working. So
simply extending the button control is not a valid solution.

I know the response to this will be greatly appreciated by all those
who have tried but failed, asked but were unanwsered.

Thanks for you replies, If you can get this to work .. great Karma
will come your way.

Regards Nick

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace TestWebControls
{

[
ToolboxData("<{0}:WebCustomControl1
runat=server></{0}:WebCustomControl1>"), PersistChildren(false),
ParseChildren(true)]
public class WebCustomControl1 :
System.Web.UI.WebControls.WebControl, INamingContainer
{

private System.Web.UI.WebControls.TextBox _TextBoxStreet ;//= new
System.Web.UI.WebControls.TextBox();
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public TextBox Street
{
get{
return _TextBoxStreet;
}
}
protected override void OnInit(EventArgs e)
{
EnsureChildControls();
base.OnInit (e);
}

protected override void CreateChildControls()
{
if(_TextBoxStreet == null)
{
_TextBoxStreet = new System.Web.UI.WebControls.TextBox();
this.Controls.Add(_TextBoxStreet);
} base.CreateChildControls();
}

protected override void Render(HtmlTextWriter output)
{
base.Render(output);
}
}
}
 
A

Alessandro Zifiglio

This is all actually working without the need to resort to manually adding
the items to viewstate etc. However you get awkward behavior. Awkward
behavoir being that, in vs.net designer the values wont get added to the
page until you set another property in the container. For example first set
the properties for your textbox, that is select some styling, add some text
to its text property and if you went into html view you wont see these
values as you expect them to be. However if you set another property from
the container that is not part of the textbox, only then are the values for
your textbox control reflected in html view and saved in the page. Now if
you went back to look you will notice this change. For the rest it all works
as expected. If you set any values at runtime in code, the values is
persisted during postback.

I had ran a small test earlier today and never got to see the textbox in the
designer and thought this werent working and went about Customizing State
Restoration and overriding saveviewstate --loadviewstate --trackviewstate
uselessly ;P

Now I see the textbox in the designer by associating a custom designer class
to the control as you will note in the example code i am pasting.

If the only problem is your wanting the values immidiately shown in html
view that is in xml form, which is the expected behavour, then I have no
idea why this is not taking place. Actually i have been stuck here myself
sometime back with a few complex types of my own when associating it with a
custom editor and i worked around dropping my editor as a whole.

I really hope someone from MS is reading this post and sheds some light
here, besides that I will go on thinking that this is a bug in the vs.net
designer. I'm pasting the complete code i have used to test this behavior.



'Code for WebCustomControl1.vb

Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.ComponentModel
Namespace CustomControls
<DefaultProperty("textbox2"), _
Designer(GetType(CustomControls.Design.SimpleDesigner)), _
ToolboxData("<{0}:WebCustomControl1
runat=server></{0}:WebCustomControl1>")> _
Public Class WebCustomControl1
Inherits System.Web.UI.WebControls.WebControl
Implements INamingContainer
Private _textbox2 As TextBox



<DesignerSerializationVisibility(DesignerSerializationVisibility.Content), _
PersistenceMode(PersistenceMode.InnerProperty), _
Bindable(True), Category("Appearance"), DefaultValue("")> _
Public Property textbox2() As TextBox
Get
If _textbox2 Is Nothing Then
_textbox2 = New TextBox()
End If
Return _textbox2
End Get
Set(ByVal Value As TextBox)
_textbox2 = Value
End Set
End Property
Friend Sub createControlsHierarchy()
Controls.Clear()
Controls.Add(New LiteralControl("<br /><br /><br /><h3>The text
box: : </h3>"))
Controls.Add(textbox2)
ChildControlsCreated = True
End Sub
Protected Overrides Sub CreateChildControls()

createControlsHierarchy()

End Sub
End Class
End Namespace

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'code for SimpleDesigner.vb

Imports System
Imports System.IO
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.Design
Imports System.Web.UI.WebControls

Namespace CustomControls.Design
Public Class SimpleDesigner
Inherits System.Web.UI.Design.ControlDesigner


Public Overrides Function GetDesignTimeHtml() As String
' Component is the instance of the component or control that
' this designer object is associated with. This property is
' inherited from System.ComponentModel.ComponentDesigner.
Dim designTimeHTML As String
Dim Instance As WebCustomControl1 = CType(Component,
WebCustomControl1)

If Not Instance.textbox2 Is Nothing Then
Instance.createControlsHierarchy()
designTimeHTML = MyBase.GetDesignTimeHtml
Return designTimeHTML
Else
Return GetEmptyDesignTimeHtml()
End If
End Function
End Class
End Namespace

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'code for webform1.aspx

<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<cc1:WebCustomControl1 id="WebCustomControl11" style="Z-INDEX: 101; LEFT:
335px; POSITION: absolute; TOP: 224px" runat="server" BackColor="#E0E0E0"
Width="158px">
<textbox2 BackColor="#C0C000" ID="textbox1">
Moi TextBox
</textbox2>
</cc1:WebCustomControl1>
<asp:Button id="Button1" style="Z-INDEX: 102; LEFT: 294px; POSITION:
absolute; TOP: 86px" runat="server" Text="Button"></asp:Button>
</form>
</body>

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'code for webform1.vb

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
If Not IsPostBack Then
WebCustomControl11.textbox2.Text = "Viewstate Working"
End If
End Sub
Alessandro Zifiglio said:
Now i see where you are getting at. Simply trying out your sample code does
not persist the data like you stated. I have tried Customizing State
Restoration with ViewState by overriding saveviewstate, loadviewstate and
trackviewstate but this didnt make a difference. I'll put in some time later
this evening and post how far i were able to get ;P


Bob Brunton said:
Thanks for the reply Alessandro,

But I actually want to expose the TextBox as a public property, so I
do need the attributes for this complex type (TextBox). I want more
than just the TextBox Text property.

Nick



"Alessandro Zifiglio" <[email protected]> wrote in
remove
working.
So
simply extending the button control is not a valid solution.

I know the response to this will be greatly appreciated by all those
who have tried but failed, asked but were unanwsered.

Thanks for you replies, If you can get this to work .. great Karma
will come your way.

Regards Nick

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace TestWebControls
{

[
ToolboxData("<{0}:WebCustomControl1
runat=server></{0}:WebCustomControl1>"), PersistChildren(false),
ParseChildren(true)]
public class WebCustomControl1 :
System.Web.UI.WebControls.WebControl, INamingContainer
{

private System.Web.UI.WebControls.TextBox _TextBoxStreet ;//= new
System.Web.UI.WebControls.TextBox();


[DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public TextBox Street
{
get{
return _TextBoxStreet;
}
}
protected override void OnInit(EventArgs e)
{
EnsureChildControls();
base.OnInit (e);
}

protected override void CreateChildControls()
{
if(_TextBoxStreet == null)
{
_TextBoxStreet = new System.Web.UI.WebControls.TextBox();
this.Controls.Add(_TextBoxStreet);
}
base.CreateChildControls();
}

protected override void Render(HtmlTextWriter output)
{
base.Render(output);
}
}
}
 
B

Bob Brunton

Thanks for your time and effort Alessandro.

I've spent a couple of days on this one, it's driving me nuts. I would
truely appreciate one of the MS team responding, just to get some
closure.

Regards Nick Harrow (alia Bob Brunton)


Alessandro Zifiglio said:
This is all actually working without the need to resort to manually adding
the items to viewstate etc. However you get awkward behavior. Awkward
behavoir being that, in vs.net designer the values wont get added to the
page until you set another property in the container. For example first set
the properties for your textbox, that is select some styling, add some text
to its text property and if you went into html view you wont see these
values as you expect them to be. However if you set another property from
the container that is not part of the textbox, only then are the values for
your textbox control reflected in html view and saved in the page. Now if
you went back to look you will notice this change. For the rest it all works
as expected. If you set any values at runtime in code, the values is
persisted during postback.

I had ran a small test earlier today and never got to see the textbox in the
designer and thought this werent working and went about Customizing State
Restoration and overriding saveviewstate --loadviewstate --trackviewstate
uselessly ;P

Now I see the textbox in the designer by associating a custom designer class
to the control as you will note in the example code i am pasting.

If the only problem is your wanting the values immidiately shown in html
view that is in xml form, which is the expected behavour, then I have no
idea why this is not taking place. Actually i have been stuck here myself
sometime back with a few complex types of my own when associating it with a
custom editor and i worked around dropping my editor as a whole.

I really hope someone from MS is reading this post and sheds some light
here, besides that I will go on thinking that this is a bug in the vs.net
designer. I'm pasting the complete code i have used to test this behavior.



'Code for WebCustomControl1.vb

Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.ComponentModel
Namespace CustomControls
<DefaultProperty("textbox2"), _
Designer(GetType(CustomControls.Design.SimpleDesigner)), _
ToolboxData("<{0}:WebCustomControl1
runat=server></{0}:WebCustomControl1>")> _
Public Class WebCustomControl1
Inherits System.Web.UI.WebControls.WebControl
Implements INamingContainer
Private _textbox2 As TextBox



<DesignerSerializationVisibility(DesignerSerializationVisibility.Content), _
PersistenceMode(PersistenceMode.InnerProperty), _
Bindable(True), Category("Appearance"), DefaultValue("")> _
Public Property textbox2() As TextBox
Get
If _textbox2 Is Nothing Then
_textbox2 = New TextBox()
End If
Return _textbox2
End Get
Set(ByVal Value As TextBox)
_textbox2 = Value
End Set
End Property
Friend Sub createControlsHierarchy()
Controls.Clear()
Controls.Add(New LiteralControl("<br /><br /><br /><h3>The text
box: : </h3>"))
Controls.Add(textbox2)
ChildControlsCreated = True
End Sub
Protected Overrides Sub CreateChildControls()

createControlsHierarchy()

End Sub
End Class
End Namespace

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'code for SimpleDesigner.vb

Imports System
Imports System.IO
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.Design
Imports System.Web.UI.WebControls

Namespace CustomControls.Design
Public Class SimpleDesigner
Inherits System.Web.UI.Design.ControlDesigner


Public Overrides Function GetDesignTimeHtml() As String
' Component is the instance of the component or control that
' this designer object is associated with. This property is
' inherited from System.ComponentModel.ComponentDesigner.
Dim designTimeHTML As String
Dim Instance As WebCustomControl1 = CType(Component,
WebCustomControl1)

If Not Instance.textbox2 Is Nothing Then
Instance.createControlsHierarchy()
designTimeHTML = MyBase.GetDesignTimeHtml
Return designTimeHTML
Else
Return GetEmptyDesignTimeHtml()
End If
End Function
End Class
End Namespace

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'code for webform1.aspx

<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<cc1:WebCustomControl1 id="WebCustomControl11" style="Z-INDEX: 101; LEFT:
335px; POSITION: absolute; TOP: 224px" runat="server" BackColor="#E0E0E0"
Width="158px">
<textbox2 BackColor="#C0C000" ID="textbox1">
Moi TextBox
</textbox2>
</cc1:WebCustomControl1>
<asp:Button id="Button1" style="Z-INDEX: 102; LEFT: 294px; POSITION:
absolute; TOP: 86px" runat="server" Text="Button"></asp:Button>
</form>
</body>

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'code for webform1.vb

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
If Not IsPostBack Then
WebCustomControl11.textbox2.Text = "Viewstate Working"
End If
End Sub
Alessandro Zifiglio said:
Now i see where you are getting at. Simply trying out your sample code does
not persist the data like you stated. I have tried Customizing State
Restoration with ViewState by overriding saveviewstate, loadviewstate and
trackviewstate but this didnt make a difference. I'll put in some time later
this evening and post how far i were able to get ;P


Bob Brunton said:
Thanks for the reply Alessandro,

But I actually want to expose the TextBox as a public property, so I
do need the attributes for this complex type (TextBox). I want more
than just the TextBox Text property.

Nick



"Alessandro Zifiglio" <[email protected]> wrote in
message news: said:
Reposting --hope there is no duplicate. I dont see my previous post ;P

hi Bob, you need to use the textbox controls text property in your get/set
accessors and not supply the control as a whole here. Your textbox control
is persisted already when your adding it to your controls collection. The
CreatechildControls method is fired after postback which reloads your
textbox into the controls collection. This is the only prerequisite for
dynamically added controls to persist their state after postback. I've also
noted that you have supplied the
DesignerSerializationVisibility(DesignerSerializationVisibility.Content)
attribute to your Get accessor property which is useless, use this for
complex types only. PersistenceMode(PersistenceMode.InnerDefaultProperty)
also is useless here. all you need to do is :

public string Street
{
get{
EnsureChildControls();
return _TextBoxStreet.Text;
set
{
EnsureChildControls();
_TextBoxStreet.Text = value;
}
}

Also note that child controls maintain their own state, and you dont have to
manually add this to viewstate to have it persist. Make sure you
remove
the
"if conditional statement" you got in CreateChildControls. All childcontrols
you add to the controls collection have to be recreated and your if
statement breaks this
No answer?

If this can't be done then does anyone have a work around?
I thought the dotnet framework could do all. I've followed all the
reference material on webcontrol building and thought this would be
trivial.

If anyone has the answer I will be more than greatfull.

REgards Nick



(e-mail address removed) (Bob Brunton) wrote in message
Hi,

I seen, this asked a number of times at this group but still have not
seen any complete/rectified/fixed code.

I have created a Composite WebControl, Added a button to it and
exposed this child button as a property. But the properties are not
persisting at design-time. Are the Attributes correct? See Code below.

Now I want to add other controls to this, when/if I get it
working.
So
simply extending the button control is not a valid solution.

I know the response to this will be greatly appreciated by all those
who have tried but failed, asked but were unanwsered.

Thanks for you replies, If you can get this to work .. great Karma
will come your way.

Regards Nick

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace TestWebControls
{

[
ToolboxData("<{0}:WebCustomControl1
runat=server></{0}:WebCustomControl1>"), PersistChildren(false),
ParseChildren(true)]
public class WebCustomControl1 :
System.Web.UI.WebControls.WebControl, INamingContainer
{

private System.Web.UI.WebControls.TextBox _TextBoxStreet ;//= new
System.Web.UI.WebControls.TextBox();


[DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public TextBox Street
{
get{
return _TextBoxStreet;
}
}
protected override void OnInit(EventArgs e)
{
EnsureChildControls();
base.OnInit (e);
}

protected override void CreateChildControls()
{
if(_TextBoxStreet == null)
{
_TextBoxStreet = new System.Web.UI.WebControls.TextBox();
this.Controls.Add(_TextBoxStreet);
} base.CreateChildControls();
}

protected override void Render(HtmlTextWriter output)
{
base.Render(output);
}
}
}
 
B

Bob Brunton

Still no response from microsoft?

I will understand if there is a good reason why other controls can't
be exposed as public properties in a composite control. But I can't
work it out.
I have applied all the attributes.

I have included full source code at the beginning of this thread.

Thanks for your time and effort Alessandro.

I've spent a couple of days on this one, it's driving me nuts. I would
truely appreciate one of the MS team responding, just to get some
closure.

Regards Nick Harrow (alia Bob Brunton)


Alessandro Zifiglio said:
This is all actually working without the need to resort to manually adding
the items to viewstate etc. However you get awkward behavior. Awkward
behavoir being that, in vs.net designer the values wont get added to the
page until you set another property in the container. For example first set
the properties for your textbox, that is select some styling, add some text
to its text property and if you went into html view you wont see these
values as you expect them to be. However if you set another property from
the container that is not part of the textbox, only then are the values for
your textbox control reflected in html view and saved in the page. Now if
you went back to look you will notice this change. For the rest it all works
as expected. If you set any values at runtime in code, the values is
persisted during postback.

I had ran a small test earlier today and never got to see the textbox in the
designer and thought this werent working and went about Customizing State
Restoration and overriding saveviewstate --loadviewstate --trackviewstate
uselessly ;P

Now I see the textbox in the designer by associating a custom designer class
to the control as you will note in the example code i am pasting.

If the only problem is your wanting the values immidiately shown in html
view that is in xml form, which is the expected behavour, then I have no
idea why this is not taking place. Actually i have been stuck here myself
sometime back with a few complex types of my own when associating it with a
custom editor and i worked around dropping my editor as a whole.

I really hope someone from MS is reading this post and sheds some light
here, besides that I will go on thinking that this is a bug in the vs.net
designer. I'm pasting the complete code i have used to test this behavior.



'Code for WebCustomControl1.vb

Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.ComponentModel
Namespace CustomControls
<DefaultProperty("textbox2"), _
Designer(GetType(CustomControls.Design.SimpleDesigner)), _
ToolboxData("<{0}:WebCustomControl1
runat=server></{0}:WebCustomControl1>")> _
Public Class WebCustomControl1
Inherits System.Web.UI.WebControls.WebControl
Implements INamingContainer
Private _textbox2 As TextBox



<DesignerSerializationVisibility(DesignerSerializationVisibility.Content), _
PersistenceMode(PersistenceMode.InnerProperty), _
Bindable(True), Category("Appearance"), DefaultValue("")> _
Public Property textbox2() As TextBox
Get
If _textbox2 Is Nothing Then
_textbox2 = New TextBox()
End If
Return _textbox2
End Get
Set(ByVal Value As TextBox)
_textbox2 = Value
End Set
End Property
Friend Sub createControlsHierarchy()
Controls.Clear()
Controls.Add(New LiteralControl("<br /><br /><br /><h3>The text
box: : </h3>"))
Controls.Add(textbox2)
ChildControlsCreated = True
End Sub
Protected Overrides Sub CreateChildControls()

createControlsHierarchy()

End Sub
End Class
End Namespace

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'code for SimpleDesigner.vb

Imports System
Imports System.IO
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.Design
Imports System.Web.UI.WebControls

Namespace CustomControls.Design
Public Class SimpleDesigner
Inherits System.Web.UI.Design.ControlDesigner


Public Overrides Function GetDesignTimeHtml() As String
' Component is the instance of the component or control that
' this designer object is associated with. This property is
' inherited from System.ComponentModel.ComponentDesigner.
Dim designTimeHTML As String
Dim Instance As WebCustomControl1 = CType(Component,
WebCustomControl1)

If Not Instance.textbox2 Is Nothing Then
Instance.createControlsHierarchy()
designTimeHTML = MyBase.GetDesignTimeHtml
Return designTimeHTML
Else
Return GetEmptyDesignTimeHtml()
End If
End Function
End Class
End Namespace

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'code for webform1.aspx

<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<cc1:WebCustomControl1 id="WebCustomControl11" style="Z-INDEX: 101; LEFT:
335px; POSITION: absolute; TOP: 224px" runat="server" BackColor="#E0E0E0"
Width="158px">
<textbox2 BackColor="#C0C000" ID="textbox1">
Moi TextBox
</textbox2>
</cc1:WebCustomControl1>
<asp:Button id="Button1" style="Z-INDEX: 102; LEFT: 294px; POSITION:
absolute; TOP: 86px" runat="server" Text="Button"></asp:Button>
</form>
</body>

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'code for webform1.vb

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
If Not IsPostBack Then
WebCustomControl11.textbox2.Text = "Viewstate Working"
End If
End Sub
Alessandro Zifiglio said:
Now i see where you are getting at. Simply trying out your sample code does
not persist the data like you stated. I have tried Customizing State
Restoration with ViewState by overriding saveviewstate, loadviewstate and
trackviewstate but this didnt make a difference. I'll put in some time later
this evening and post how far i were able to get ;P


Thanks for the reply Alessandro,

But I actually want to expose the TextBox as a public property, so I
do need the attributes for this complex type (TextBox). I want more
than just the TextBox Text property.

Nick



"Alessandro Zifiglio" <[email protected]> wrote in
message news: said:
Reposting --hope there is no duplicate. I dont see my previous post ;P

hi Bob, you need to use the textbox controls text property in your get/set
accessors and not supply the control as a whole here. Your textbox control
is persisted already when your adding it to your controls collection. The
CreatechildControls method is fired after postback which reloads your
textbox into the controls collection. This is the only prerequisite for
dynamically added controls to persist their state after postback. I've also
noted that you have supplied the
DesignerSerializationVisibility(DesignerSerializationVisibility.Content)
attribute to your Get accessor property which is useless, use this for
complex types only. PersistenceMode(PersistenceMode.InnerDefaultProperty)
also is useless here. all you need to do is :

public string Street
{
get{
EnsureChildControls();
return _TextBoxStreet.Text;
set
{
EnsureChildControls();
_TextBoxStreet.Text = value;
}
}

Also note that child controls maintain their own state, and you dont have to
manually add this to viewstate to have it persist. Make sure you remove
the
"if conditional statement" you got in CreateChildControls. All childcontrols
you add to the controls collection have to be recreated and your if
statement breaks this
No answer?

If this can't be done then does anyone have a work around?
I thought the dotnet framework could do all. I've followed all the
reference material on webcontrol building and thought this would be
trivial.

If anyone has the answer I will be more than greatfull.

REgards Nick



(e-mail address removed) (Bob Brunton) wrote in message
Hi,

I seen, this asked a number of times at this group but still have not
seen any complete/rectified/fixed code.

I have created a Composite WebControl, Added a button to it and
exposed this child button as a property. But the properties are not
persisting at design-time. Are the Attributes correct? See Code below.

Now I want to add other controls to this, when/if I get it working.
So
simply extending the button control is not a valid solution.

I know the response to this will be greatly appreciated by all those
who have tried but failed, asked but were unanwsered.

Thanks for you replies, If you can get this to work .. great Karma
will come your way.

Regards Nick

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace TestWebControls
{

[
ToolboxData("<{0}:WebCustomControl1
runat=server></{0}:WebCustomControl1>"), PersistChildren(false),
ParseChildren(true)]
public class WebCustomControl1 :
System.Web.UI.WebControls.WebControl, INamingContainer
{

private System.Web.UI.WebControls.TextBox _TextBoxStreet ;//= new
System.Web.UI.WebControls.TextBox();


[DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public TextBox Street
{
get{
return _TextBoxStreet;
}
}
protected override void OnInit(EventArgs e)
{
EnsureChildControls();
base.OnInit (e);
}

protected override void CreateChildControls()
{
if(_TextBoxStreet == null)
{
_TextBoxStreet = new System.Web.UI.WebControls.TextBox();
this.Controls.Add(_TextBoxStreet);
} base.CreateChildControls();
}

protected override void Render(HtmlTextWriter output)
{
base.Render(output);
}
}
}
 
A

Alessandro Zifiglio

Bob, me again ;P

I gave this another go and the only way to get this working is to override
every property in the control you want to expose and manually override each
property you want exposed with NotifyParentProperty(True). For complex
types, to make the Parent property receive notification of changes in the
child property's values, the child property must be marked with
NotifyParentProperty(True). I have a hunch that none of the web controls
have this attribute set to true by default and the only way around is to
manually override each attribute and set it to true.


Bob Brunton said:
Still no response from microsoft?

I will understand if there is a good reason why other controls can't
be exposed as public properties in a composite control. But I can't
work it out.
I have applied all the attributes.

I have included full source code at the beginning of this thread.

(e-mail address removed) (Bob Brunton) wrote in message
Thanks for your time and effort Alessandro.

I've spent a couple of days on this one, it's driving me nuts. I would
truely appreciate one of the MS team responding, just to get some
closure.

Regards Nick Harrow (alia Bob Brunton)


"Alessandro Zifiglio" <[email protected]> wrote in
message news: said:
This is all actually working without the need to resort to manually adding
the items to viewstate etc. However you get awkward behavior. Awkward
behavoir being that, in vs.net designer the values wont get added to the
page until you set another property in the container. For example first set
the properties for your textbox, that is select some styling, add some text
to its text property and if you went into html view you wont see these
values as you expect them to be. However if you set another property from
the container that is not part of the textbox, only then are the values for
your textbox control reflected in html view and saved in the page. Now if
you went back to look you will notice this change. For the rest it all works
as expected. If you set any values at runtime in code, the values is
persisted during postback.

I had ran a small test earlier today and never got to see the textbox in the
designer and thought this werent working and went about Customizing State
Restoration and overriding saveviewstate --loadviewstate --trackviewstate
uselessly ;P

Now I see the textbox in the designer by associating a custom designer class
to the control as you will note in the example code i am pasting.

If the only problem is your wanting the values immidiately shown in html
view that is in xml form, which is the expected behavour, then I have no
idea why this is not taking place. Actually i have been stuck here myself
sometime back with a few complex types of my own when associating it with a
custom editor and i worked around dropping my editor as a whole.

I really hope someone from MS is reading this post and sheds some light
here, besides that I will go on thinking that this is a bug in the vs.net
designer. I'm pasting the complete code i have used to test this behavior.



'Code for WebCustomControl1.vb

Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.ComponentModel
Namespace CustomControls
<DefaultProperty("textbox2"), _
Designer(GetType(CustomControls.Design.SimpleDesigner)), _
ToolboxData("<{0}:WebCustomControl1
runat=server></{0}:WebCustomControl1>")> _
Public Class WebCustomControl1
Inherits System.Web.UI.WebControls.WebControl
Implements INamingContainer
Private _textbox2 As TextBox



<DesignerSerializationVisibility(DesignerSerializationVisibility.Content), _
PersistenceMode(PersistenceMode.InnerProperty), _
Bindable(True), Category("Appearance"), DefaultValue("")> _
Public Property textbox2() As TextBox
Get
If _textbox2 Is Nothing Then
_textbox2 = New TextBox()
End If
Return _textbox2
End Get
Set(ByVal Value As TextBox)
_textbox2 = Value
End Set
End Property
Friend Sub createControlsHierarchy()
Controls.Clear()
Controls.Add(New LiteralControl("<br /><br /><br /><h3>The text
box: : </h3>"))
Controls.Add(textbox2)
ChildControlsCreated = True
End Sub
Protected Overrides Sub CreateChildControls()

createControlsHierarchy()

End Sub
End Class
End Namespace

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'code for SimpleDesigner.vb

Imports System
Imports System.IO
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.Design
Imports System.Web.UI.WebControls

Namespace CustomControls.Design
Public Class SimpleDesigner
Inherits System.Web.UI.Design.ControlDesigner


Public Overrides Function GetDesignTimeHtml() As String
' Component is the instance of the component or control that
' this designer object is associated with. This property is
' inherited from System.ComponentModel.ComponentDesigner.
Dim designTimeHTML As String
Dim Instance As WebCustomControl1 = CType(Component,
WebCustomControl1)

If Not Instance.textbox2 Is Nothing Then
Instance.createControlsHierarchy()
designTimeHTML = MyBase.GetDesignTimeHtml
Return designTimeHTML
Else
Return GetEmptyDesignTimeHtml()
End If
End Function
End Class
End Namespace

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'code for webform1.aspx

<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<cc1:WebCustomControl1 id="WebCustomControl11" style="Z-INDEX: 101; LEFT:
335px; POSITION: absolute; TOP: 224px" runat="server" BackColor="#E0E0E0"
Width="158px">
<textbox2 BackColor="#C0C000" ID="textbox1">
Moi TextBox
</textbox2>
</cc1:WebCustomControl1>
<asp:Button id="Button1" style="Z-INDEX: 102; LEFT: 294px; POSITION:
absolute; TOP: 86px" runat="server" Text="Button"></asp:Button>
</form>
</body>

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'code for webform1.vb

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
If Not IsPostBack Then
WebCustomControl11.textbox2.Text = "Viewstate Working"
End If
End Sub
message Now i see where you are getting at. Simply trying out your sample
code
does
not persist the data like you stated. I have tried Customizing State
Restoration with ViewState by overriding saveviewstate, loadviewstate and
trackviewstate but this didnt make a difference. I'll put in some
time
later
this evening and post how far i were able to get ;P


Thanks for the reply Alessandro,

But I actually want to expose the TextBox as a public property, so I
do need the attributes for this complex type (TextBox). I want more
than just the TextBox Text property.

Nick



"Alessandro Zifiglio" <[email protected]>
wrote in
message news: said:
Reposting --hope there is no duplicate. I dont see my previous post ;P

hi Bob, you need to use the textbox controls text property in
your
get/set
accessors and not supply the control as a whole here. Your
textbox
control
is persisted already when your adding it to your controls
collection.
The
CreatechildControls method is fired after postback which reloads your
textbox into the controls collection. This is the only
prerequisite
for
dynamically added controls to persist their state after
postback. I've
also
noted that you have supplied the
DesignerSerializationVisibility(DesignerSerializationVisibility.Content)
attribute to your Get accessor property which is useless, use this for
complex types only. PersistenceMode(PersistenceMode.InnerDefaultProperty)
also is useless here. all you need to do is :

public string Street
{
get{
EnsureChildControls();
return _TextBoxStreet.Text;
set
{
EnsureChildControls();
_TextBoxStreet.Text = value;
}
}

Also note that child controls maintain their own state, and you
dont
have to
manually add this to viewstate to have it persist. Make sure you
remove
the
"if conditional statement" you got in CreateChildControls. All childcontrols
you add to the controls collection have to be recreated and your if
statement breaks this
No answer?

If this can't be done then does anyone have a work around?
I thought the dotnet framework could do all. I've followed all the
reference material on webcontrol building and thought this would be
trivial.

If anyone has the answer I will be more than greatfull.

REgards Nick



(e-mail address removed) (Bob Brunton) wrote in message
Hi,

I seen, this asked a number of times at this group but still
have
not
seen any complete/rectified/fixed code.

I have created a Composite WebControl, Added a button to it and
exposed this child button as a property. But the properties
are
not
persisting at design-time. Are the Attributes correct? See
Code
below.
Now I want to add other controls to this, when/if I get it
working.
So
simply extending the button control is not a valid solution.

I know the response to this will be greatly appreciated by
all
those
who have tried but failed, asked but were unanwsered.

Thanks for you replies, If you can get this to work .. great Karma
will come your way.

Regards Nick

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace TestWebControls
{

[
ToolboxData("<{0}:WebCustomControl1
runat=server></{0}:WebCustomControl1>"), PersistChildren(false),
ParseChildren(true)]
public class WebCustomControl1 :
System.Web.UI.WebControls.WebControl, INamingContainer
{

private System.Web.UI.WebControls.TextBox _TextBoxStreet ;//= new
System.Web.UI.WebControls.TextBox();
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public TextBox Street
{
get{
return _TextBoxStreet;
}
}
protected override void OnInit(EventArgs e)
{
EnsureChildControls();
base.OnInit (e);
}

protected override void CreateChildControls()
{
if(_TextBoxStreet == null)
{
_TextBoxStreet = new System.Web.UI.WebControls.TextBox();
this.Controls.Add(_TextBoxStreet);
} base.CreateChildControls();
}

protected override void Render(HtmlTextWriter output)
{
base.Render(output);
}
}
}
 
A

Alessandro Zifiglio

and in case its not clear where i'm getting at, your going to have to make a
base class that inherits from say for example textbox control, and then
override every property for textbox you want exposed.

So finally in your control, when exposing a textbox control it will look
like the following :

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public MyCustomTextBox Street
{
//note above MyCustomTextBox class which inherits
//from textbox and has overridden properties
//with NotifyParentPoperty(True)
get{
return _TextBoxStreet;
}
}

Alessandro Zifiglio said:
Bob, me again ;P

I gave this another go and the only way to get this working is to override
every property in the control you want to expose and manually override each
property you want exposed with NotifyParentProperty(True). For complex
types, to make the Parent property receive notification of changes in the
child property's values, the child property must be marked with
NotifyParentProperty(True). I have a hunch that none of the web controls
have this attribute set to true by default and the only way around is to
manually override each attribute and set it to true.


Bob Brunton said:
Still no response from microsoft?

I will understand if there is a good reason why other controls can't
be exposed as public properties in a composite control. But I can't
work it out.
I have applied all the attributes.

I have included full source code at the beginning of this thread.

(e-mail address removed) (Bob Brunton) wrote in message
in
some
Now
all
textbox
in the designer
have
no <DesignerSerializationVisibility(DesignerSerializationVisibility.Content), _
/> said:
101;
so
reloads
you
your
all
still
it
properties
great
Karma
will come your way.

Regards Nick

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace TestWebControls
{

[
ToolboxData("<{0}:WebCustomControl1
runat=server></{0}:WebCustomControl1>"), PersistChildren(false),
ParseChildren(true)]
public class WebCustomControl1 :
System.Web.UI.WebControls.WebControl, INamingContainer
{

private System.Web.UI.WebControls.TextBox _TextBoxStreet ;//= new
System.Web.UI.WebControls.TextBox();



[DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public TextBox Street
{
get{
return _TextBoxStreet;
}
}
protected override void OnInit(EventArgs e)
{
EnsureChildControls();
base.OnInit (e);
}

protected override void CreateChildControls()
{
if(_TextBoxStreet == null)
{
_TextBoxStreet = new System.Web.UI.WebControls.TextBox();
this.Controls.Add(_TextBoxStreet);
}
base.CreateChildControls();
}

protected override void Render(HtmlTextWriter output)
{
base.Render(output);
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top