Accessing Properties of Custom Controls child Controls

M

Moldy

I am using a Custom Control on a page which renders a button control
if required. I need to access the child button control's properties
(i.e. UniqueID) on the page but cannot get them to come through on
first load of the page, only on postback. Can anyone help!

Code is below

On first load, only the button is displayed, click the button and the
UniqueID appears.

TIA

Moldy

********** START CODE FOR CUSTOM CONTROL **********
Imports System.ComponentModel
Imports System.Web.UI
Imports System.Web.UI.WebControls

Public Class ButtonControl
Inherits System.Web.UI.WebControls.WebControl
Implements INamingContainer

Dim bMyButton As Boolean

<Browsable(True), DefaultValue(False)> Public Property
ShowMyButton() As Boolean
Get
Return bMyButton
End Get
Set(ByVal Value As Boolean)
bMyButton = Value
End Set
End Property

Public myButton As New Button()

Protected Overrides Sub CreateChildControls()
With myButton
.Text = "Click Me!"
.Visible = False
End With
Controls.Add(myButton)
End Sub

Private Sub ButtonControl_PreRender(ByVal sender As Object,
ByVal e As System.EventArgs) Handles MyBase.PreRender
If bMyButton Then
myButton.Visible = True
Else
myButton.Visible = False
End If
End Sub
End Class
********** END CODE FOR CUSTOM CONTROL **********

********** START CODE FOR ASPX PAGE **********
<%@ Register TagPrefix="CompControl" Namespace="CompControl"
Assembly="CompControl" %>
<%@ Page Language="vb" AutoEventWireup="false"
Codebehind="Default.aspx.vb" Inherits="ChildControlTest.WebForm1"%>
<html>
<body>
<form id="Form1" method="post" runat="server">
<compcontrol:buttoncontrol
id="myButtonControl" runat="server"></compcontrol:buttoncontrol>
</form>
</body>
</html>
********** END CODE FOR ASPX PAGE **********

********** START CODE FOR ASPX.VB PAGE **********
Public Class WebForm1
Inherits System.Web.UI.Page
Protected WithEvents myButtonControl As
CompControl.ButtonControl

Private Sub Page_Load(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles MyBase.Load
myButtonControl.ShowMyButton = True
Response.Write(myButtonControl.myButton.UniqueID)
End Sub

End Class
********** END CODE FOR ASPX.VB PAGE **********
 
T

Teemu Keiski

Just call it every time before you'd need to access child controls (member
that references child controls etc). Calling EnsureChildControls makes sure
child controls (created in CreateChildControls) are created. One example is
calling it in accessor for top-level property that returns some proeprty
value from the child control(s).

--
Teemu Keiski
MCP, Designer/Developer
Mansoft tietotekniikka Oy
http://www.mansoft.fi

AspInsiders Member, www.aspinsiders.com
ASP.NET Forums Moderator, www.asp.net
AspAlliance Columnist, www.aspalliance.com
 
J

Jimmy [Used-Disks]

[snip]
Public myButton As New Button()

You should declare this as a read-only property and be sure to call
EnsureChildControls() before accessing it:

Dim _MyButton As Boolean
Public Property MyButton() As Boolean
Get
EnsureChildControls()
Return _MyButton
End Get
End Property
Protected Overrides Sub CreateChildControls()
With myButton
.Text = "Click Me!"
.Visible = False
End With
Controls.Add(myButton)
End Sub

This is where you should *create* the child controls, not initialize them:

Protected Overrides Sub CreateChildControls()
_MyButton = New Button()
With _MyButton
.Text = "Click Me!"
.Visible = False
End With
Controls.Add(_MyButton)
End Sub
Private Sub ButtonControl_PreRender(ByVal sender As Object,
ByVal e As System.EventArgs) Handles MyBase.PreRender
If bMyButton Then
myButton.Visible = True
Else
myButton.Visible = False
End If
End Sub

Why use an internal variable? Why not just read/write directly to
MyButton.Visible for the ShowMyButton property?

Example:

<Browsable(True), DefaultValue(False)>
Public Property ShowMyButton() As Boolean
Get
Return MyButton.Visible
End Get
Set(ByVal Value As Boolean)
MyButton.Visible = Value
End Set
End Property

You could then exclude the step of assigning _MyButton.Visible in your
CreateChildControls method:

Protected Overrides Sub CreateChildControls()
_MyButton = New Button()
With _MyButton
.Text = "Click Me!"
End With
Controls.Add(_MyButton)
End Sub
 
M

Moldy

[Snip]

OK, so I got that working now except one problem.

All the buttons in my object default to being on even tho I have set
DefaultValue(False) on the Property.

Why is this? The actual control I am working on has 28 buttons and I
don't really want to have to switch them all off each time it is
called (which is a lot!)

Any ideas?

New code is below....

TIA

Moldy

******CODE******

Imports System.ComponentModel
Imports System.Web.UI
Imports System.Web.UI.WebControls

Public Class ButtonControl
Inherits System.Web.UI.WebControls.WebControl
Implements INamingContainer

Dim _myButton As Button
Public ReadOnly Property MyButton() As Button
Get
ensurechildcontrols()
Return _myButton
End Get
End Property

<Browsable(True), DefaultValue(False)> Public Property
ShowMyButton() As Boolean
Get
Return MyButton.Visible
End Get
Set(ByVal Value As Boolean)
MyButton.Visible = Value
End Set
End Property

Protected Overrides Sub CreateChildControls()
_myButton = New Button()
With _myButton
.Text = "Click Me!"
End With
Controls.Add(_myButton)
End Sub

End Class
 
J

John Saunders

Moldy said:
[Snip]

OK, so I got that working now except one problem.

All the buttons in my object default to being on even tho I have set
DefaultValue(False) on the Property.

Why is this? The actual control I am working on has 28 buttons and I
don't really want to have to switch them all off each time it is
called (which is a lot!)

Any ideas?

New code is below....

TIA

Moldy

******CODE******

Imports System.ComponentModel
Imports System.Web.UI
Imports System.Web.UI.WebControls

Public Class ButtonControl
Inherits System.Web.UI.WebControls.WebControl
Implements INamingContainer

Dim _myButton As Button
Public ReadOnly Property MyButton() As Button
Get
ensurechildcontrols()
Return _myButton
End Get
End Property

<Browsable(True), DefaultValue(False)> Public Property
ShowMyButton() As Boolean
Get
Return MyButton.Visible
End Get
Set(ByVal Value As Boolean)
MyButton.Visible = Value
End Set
End Property

Protected Overrides Sub CreateChildControls()
_myButton = New Button()
With _myButton
.Text = "Click Me!"
End With
Controls.Add(_myButton)
End Sub

End Class

When you created your button in CreateChildControls, you didn't touch the
Visible property - it defaults to true.
 
J

Jimmy [Used-Disks]

Hey Moldy, I'm glad I could help :).
Protected Overrides Sub CreateChildControls()
_myButton = New Button()
With _myButton
.Text = "Click Me!"

Add this:

.Visible = False
End With
Controls.Add(_myButton)
End Sub

The reason, as John pointed out, is that the Button's visible property
defaults to true and that is your control to ignore your default attribute.
By setting the .Visible property on the buttons creation, you are explicitly
turing this off.
 
M

Moldy

Hey Moldy, I'm glad I could help :).


Add this:

.Visible = False


The reason, as John pointed out, is that the Button's visible property
defaults to true and that is your control to ignore your default attribute.
By setting the .Visible property on the buttons creation, you are explicitly
turing this off.

Great stuff!

I did have that in my original code but took it out as you pointed out
that it can be set directly from the Show property. I thought that it
would take the default from the property.

Thanks for all your help. My app is much leaner now!

Regards,

Moldy
 

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,982
Messages
2,570,186
Members
46,739
Latest member
Clint8040

Latest Threads

Top