Child user control accessing parent properties

Discussion in 'ASP .Net Building Controls' started by Michael, Jul 13, 2004.

  1. Michael

    Michael Guest

    We have a user control (Titlebar) that loads other user controls (children)
    into itself based on a property set in the HTML:

    <fss:Titlebar id="empStmtListing" runat="server"
    UserControl="StatementListing.ascx" Width="90"
    HelpId="1" ListingType="3"></fss:Titlebar>

    Some of the children user controls need properties set to execute. We would
    put these properties in the HTML of the parent,
    for example, the ListingType property above. Is there anyway that
    StatementListing.ascx can access and read the ListingType
    property? Or will our Titlebar user control always have to pass the
    properties into the child control?

    Thanks

    --
    Michael W. Wilson
    Raytheon Company
    Sr. Business Programmer
     
    Michael, Jul 13, 2004
    #1
    1. Advertising

  2. "Michael" <> wrote in message
    news:eek:0WIc.5$...
    > We have a user control (Titlebar) that loads other user controls

    (children)
    > into itself based on a property set in the HTML:
    >
    > <fss:Titlebar id="empStmtListing" runat="server"
    > UserControl="StatementListing.ascx" Width="90"
    > HelpId="1" ListingType="3"></fss:Titlebar>
    >
    > Some of the children user controls need properties set to execute. We

    would
    > put these properties in the HTML of the parent,
    > for example, the ListingType property above. Is there anyway that
    > StatementListing.ascx can access and read the ListingType
    > property? Or will our Titlebar user control always have to pass the
    > properties into the child control?


    It's really bad form for a child control to know too much about its parent.
    Instead, let the parent tell the child what it needs to know.
    --
    John Saunders
    johnwsaundersiii at hotmail
     
    John Saunders, Jul 14, 2004
    #2
    1. Advertising

  3. Michael

    XicoLoKo Guest

    Another approach would be to have a base usercontrol class, lets say TitleBarChildControlBase, that exposes those properties from it's parent.

    User controls that inherit TitleBarChildControlBase would be used only inside the TitleBar.

    - xicoloko -

    "John Saunders" wrote:

    > "Michael" <> wrote in message
    > news:eek:0WIc.5$...
    > > We have a user control (Titlebar) that loads other user controls

    > (children)
    > > into itself based on a property set in the HTML:
    > >
    > > <fss:Titlebar id="empStmtListing" runat="server"
    > > UserControl="StatementListing.ascx" Width="90"
    > > HelpId="1" ListingType="3"></fss:Titlebar>
    > >
    > > Some of the children user controls need properties set to execute. We

    > would
    > > put these properties in the HTML of the parent,
    > > for example, the ListingType property above. Is there anyway that
    > > StatementListing.ascx can access and read the ListingType
    > > property? Or will our Titlebar user control always have to pass the
    > > properties into the child control?

    >
    > It's really bad form for a child control to know too much about its parent.
    > Instead, let the parent tell the child what it needs to know.
    > --
    > John Saunders
    > johnwsaundersiii at hotmail
    >
    >
    >
     
    XicoLoKo, Jul 15, 2004
    #3
  4. "XicoLoKo" <> wrote in message
    news:...
    > Another approach would be to have a base usercontrol class, lets say

    TitleBarChildControlBase, that exposes those properties from it's parent.
    >
    > User controls that inherit TitleBarChildControlBase would be used only

    inside the TitleBar.

    Ok, I originally read the OP as asking a question about user controls in
    general. If, instead, the user controls in question will _always_ be used
    inside of the same parent control, then knowing about their parent would be
    ok.

    In this case, it would be ok if the user controls were to cast their Parent
    property to the type of the parent:

    VB.NET:

    Dim tbParentTitlebar As Titlebar = DirectCast(Parent, GetType(Titlebar))
    ' Can now use tbParentTitlebar.ListingType

    C#:

    Titlebar tbParentTitlebar = (Titlebar) Parent;
    // Can now use tbParentTitlebar.ListingType
    --
    John Saunders
    johnwsaundersiii at hotmail



    > "John Saunders" wrote:
    >
    > > "Michael" <> wrote in message
    > > news:eek:0WIc.5$...
    > > > We have a user control (Titlebar) that loads other user controls

    > > (children)
    > > > into itself based on a property set in the HTML:
    > > >
    > > > <fss:Titlebar id="empStmtListing" runat="server"
    > > > UserControl="StatementListing.ascx" Width="90"
    > > > HelpId="1" ListingType="3"></fss:Titlebar>
    > > >
    > > > Some of the children user controls need properties set to execute. We

    > > would
    > > > put these properties in the HTML of the parent,
    > > > for example, the ListingType property above. Is there anyway that
    > > > StatementListing.ascx can access and read the ListingType
    > > > property? Or will our Titlebar user control always have to pass the
    > > > properties into the child control?

    > >
    > > It's really bad form for a child control to know too much about its

    parent.
    > > Instead, let the parent tell the child what it needs to know.
    > > --
    > > John Saunders
    > > johnwsaundersiii at hotmail
    > >
    > >
    > >
     
    John Saunders, Jul 15, 2004
    #4
  5. Sorry, that should be Parent.aspx where it says Parent.ascx; I've already realized this won't work because (Sub)Control.ascx's parent is a Panel (not shown), but you get the idea -- what's the "right" way?

    "Donald Welker" wrote:

    > I have a parent web page that has dynamic child controls, some of which are nested. I would like for all of the child controls to have access to the parent's service objects so they can use the same database connection etc.
    >
    > Since it is possible for a control to be instantiated from either the parent page directly or from a control on the parent page, is it possible/OK for me to cast the parent Page to a Control in order to access the shared object(s)?
    >
    > Summarized example: Suppose Parent.aspx loads and displays SubControl.ascx either directly in a panel, or as a component of Control.ascx instead. In Parent.ascx I write:
    > ...
    > Friend Log as LogOps ' routines to access the log
    > ...
    > Then in both Control.ascx and SubControl.ascx I write:
    > ...
    > Dim Mom as Control = DirectCast(Parent,Control)
    > Dim Log as LogOps = Mom.Log
    > ...
    > or do I have to somehow determine whether the parent is a page or a control?
    >
     
    Donald Welker, Jul 28, 2004
    #5
  6. Sorry, that should be Parent.aspx where it says Parent.ascx; I've already realized this won't work because (Sub)Control.ascx's parent is a Panel (not shown), but you get the idea -- what's the "right" way?

    "Donald Welker" wrote:

    > I have a parent web page that has dynamic child controls, some of which are nested. I would like for all of the child controls to have access to the parent's service objects so they can use the same database connection etc.
    >
    > Since it is possible for a control to be instantiated from either the parent page directly or from a control on the parent page, is it possible/OK for me to cast the parent Page to a Control in order to access the shared object(s)?
    >
    > Summarized example: Suppose Parent.aspx loads and displays SubControl.ascx either directly in a panel, or as a component of Control.ascx instead. In Parent.ascx I write:
    > ...
    > Friend Log as LogOps ' routines to access the log
    > ...
    > Then in both Control.ascx and SubControl.ascx I write:
    > ...
    > Dim Mom as Control = DirectCast(Parent,Control)
    > Dim Log as LogOps = Mom.Log
    > ...
    > or do I have to somehow determine whether the parent is a page or a control?
    >
     
    Donald Welker, Jul 28, 2004
    #6
  7. "Donald Welker" <Donald.WelkerN0$SPAM@N0$SPAM.navy.mil> wrote in message
    news:...
    > I have a parent web page that has dynamic child controls, some of which

    are nested. I would like for all of the child controls to have access to
    the parent's service objects so they can use the same database connection
    etc.
    >
    > Since it is possible for a control to be instantiated from either the

    parent page directly or from a control on the parent page, is it possible/OK
    for me to cast the parent Page to a Control in order to access the shared
    object(s)?
    >
    > Summarized example: Suppose Parent.aspx loads and displays

    SubControl.ascx either directly in a panel, or as a component of
    Control.ascx instead. In Parent.ascx I write:
    > ...
    > Friend Log as LogOps ' routines to access the log
    > ...
    > Then in both Control.ascx and SubControl.ascx I write:
    > ...
    > Dim Mom as Control = DirectCast(Parent,Control)
    > Dim Log as LogOps = Mom.Log
    > ...
    > or do I have to somehow determine whether the parent is a page or a

    control?

    Donald,

    My first suggestion would be to set "Options Strict" on. You may find it
    enlightening.

    Second, I recommend that the parent should pass to the child anything which
    is owned by the parent but required by the child. In your case, I would add
    a Log property to the child controls and I'd let the parent set that
    property after it instantiates the child controls. Presumably, your "Log"
    object is pretty much read-only? I wouldn't want multiple child controls
    changing it in an unpredictable sequence.

    BTW, I wouldn't worry about sharing database connections at all. The
    connections will likely be pooled, so a second, "duplicate" connection
    shouldn't use many additional resources. Also, it doesn't seem right for a
    child control to be using the parent's connection, in effect taking it over
    from the parent. The child could then do things "behind the parent's back",
    which is not a good idea.
    --
    John Saunders
    johnwsaundersiii at hotmail
     
    John Saunders, Jul 29, 2004
    #7
  8. The log object in this case is a set of shim routines to write to the NT event log, so it's not much of a risk at the moment. I'm writing a "wizard" to help build a complex document and have broken up sections into about a dozen web controls, each with it's own edit and display panel. When the user is done the final document is recorded in a database and presented for printing, so each control is supposed to be smart enough to edit its portion of the draft document and display its fields in the final version. My original thought was to write one module to communicate with the database and share it throughout, but it occurs to me that the controls will have different data adapters and don't need access to each others' data -- but I need to make sure the connection string is shared.

    What I've now done is created a "template" control from which to derive the others, but now the derived controls won't load in the designer: "Abstract Class" -- do I need to add a reference to the template or can I no longer use the designer?

    "John Saunders" wrote:

    > "Donald Welker" <Donald.WelkerN0$SPAM@N0$SPAM.navy.mil> wrote in message
    > news:...
    > > I have a parent web page that has dynamic child controls, some of which

    > are nested. I would like for all of the child controls to have access to
    > the parent's service objects so they can use the same database connection
    > etc.
    > >
    > > Since it is possible for a control to be instantiated from either the

    > parent page directly or from a control on the parent page, is it possible/OK
    > for me to cast the parent Page to a Control in order to access the shared
    > object(s)?
    > >
    > > Summarized example: Suppose Parent.aspx loads and displays

    > SubControl.ascx either directly in a panel, or as a component of
    > Control.ascx instead. In Parent.ascx I write:
    > > ...
    > > Friend Log as LogOps ' routines to access the log
    > > ...
    > > Then in both Control.ascx and SubControl.ascx I write:
    > > ...
    > > Dim Mom as Control = DirectCast(Parent,Control)
    > > Dim Log as LogOps = Mom.Log
    > > ...
    > > or do I have to somehow determine whether the parent is a page or a

    > control?
    >
    > Donald,
    >
    > My first suggestion would be to set "Options Strict" on. You may find it
    > enlightening.
    >
    > Second, I recommend that the parent should pass to the child anything which
    > is owned by the parent but required by the child. In your case, I would add
    > a Log property to the child controls and I'd let the parent set that
    > property after it instantiates the child controls. Presumably, your "Log"
    > object is pretty much read-only? I wouldn't want multiple child controls
    > changing it in an unpredictable sequence.
    >
    > BTW, I wouldn't worry about sharing database connections at all. The
    > connections will likely be pooled, so a second, "duplicate" connection
    > shouldn't use many additional resources. Also, it doesn't seem right for a
    > child control to be using the parent's connection, in effect taking it over
    > from the parent. The child could then do things "behind the parent's back",
    > which is not a good idea.
    > --
    > John Saunders
    > johnwsaundersiii at hotmail
    >
    >
    >
     
    Donald Welker, Jul 30, 2004
    #8
  9. "Donald Welker" <Donald.WelkerN0$SPAM@N0$SPAM.navy.mil> wrote in message
    news:...
    > The log object in this case is a set of shim routines to write to the NT

    event log, so it's not much of a risk at the moment. I'm writing a "wizard"
    to help build a complex document and have broken up sections into about a
    dozen web controls, each with it's own edit and display panel. When the
    user is done the final document is recorded in a database and presented for
    printing, so each control is supposed to be smart enough to edit its portion
    of the draft document and display its fields in the final version. My
    original thought was to write one module to communicate with the database
    and share it throughout, but it occurs to me that the controls will have
    different data adapters and don't need access to each others' data -- but I
    need to make sure the connection string is shared.
    >
    > What I've now done is created a "template" control from which to derive

    the others, but now the derived controls won't load in the designer:
    "Abstract Class" -- do I need to add a reference to the template or can I no
    longer use the designer?

    As to the connection and/or connection string, you could pass that into the
    controls. Just add a Connection property of type SqlConnection (or whichever
    connection type you need).

    As to the "no inherited user controls" problem - that's just another
    trade-off with user controls. The designer isn't clever enough to do what
    you want there. If you used custom controls, you wouldn't have this problem,
    but you _would_ take longer to get the project done. You can have your user
    controls all inherit from a base class, but that base class can't do
    anything as far as UI goes. I've done this successfully in the past.

    Good Luck,
    John Saunders
    johnwsaundersiii at hotmail


    > "John Saunders" wrote:
    >
    > > "Donald Welker" <Donald.WelkerN0$SPAM@N0$SPAM.navy.mil> wrote in message
    > > news:...
    > > > I have a parent web page that has dynamic child controls, some of

    which
    > > are nested. I would like for all of the child controls to have access

    to
    > > the parent's service objects so they can use the same database

    connection
    > > etc.
    > > >
    > > > Since it is possible for a control to be instantiated from either the

    > > parent page directly or from a control on the parent page, is it

    possible/OK
    > > for me to cast the parent Page to a Control in order to access the

    shared
    > > object(s)?
    > > >
    > > > Summarized example: Suppose Parent.aspx loads and displays

    > > SubControl.ascx either directly in a panel, or as a component of
    > > Control.ascx instead. In Parent.ascx I write:
    > > > ...
    > > > Friend Log as LogOps ' routines to access the log
    > > > ...
    > > > Then in both Control.ascx and SubControl.ascx I write:
    > > > ...
    > > > Dim Mom as Control = DirectCast(Parent,Control)
    > > > Dim Log as LogOps = Mom.Log
    > > > ...
    > > > or do I have to somehow determine whether the parent is a page or a

    > > control?
    > >
    > > Donald,
    > >
    > > My first suggestion would be to set "Options Strict" on. You may find it
    > > enlightening.
    > >
    > > Second, I recommend that the parent should pass to the child anything

    which
    > > is owned by the parent but required by the child. In your case, I would

    add
    > > a Log property to the child controls and I'd let the parent set that
    > > property after it instantiates the child controls. Presumably, your

    "Log"
    > > object is pretty much read-only? I wouldn't want multiple child controls
    > > changing it in an unpredictable sequence.
    > >
    > > BTW, I wouldn't worry about sharing database connections at all. The
    > > connections will likely be pooled, so a second, "duplicate" connection
    > > shouldn't use many additional resources. Also, it doesn't seem right for

    a
    > > child control to be using the parent's connection, in effect taking it

    over
    > > from the parent. The child could then do things "behind the parent's

    back",
    > > which is not a good idea.
    > > --
    > > John Saunders
    > > johnwsaundersiii at hotmail
    > >
    > >
    > >
     
    John Saunders, Jul 30, 2004
    #9
  10. "Donald Welker" <Donald.WelkerN0$SPAM@N0$SPAM.navy.mil> wrote in message
    news:...
    > What I have now are a dozen controls that are different classes. What I'd

    like to do is set all their properties at the same time. It would be really
    nice to treat them as an array or collection and loop through each of them
    to set the same properties. I guess I could use the New method as an
    alternative.


    Donald,

    If they all inherit from the same base class, then there should be no
    problem in setting all their properties at the same time. In fact, you would
    be able to use Reflection to find all of those controls and set their
    properties at once.

    Now, a different (and perhaps better) solution just struck me. Since all of
    the controls will require access to the same values of the same set of
    properties, it makes sense to encapsulate all of those properties in a
    single class. The parent page could then create a single instance of this
    class and set the properties of this single instance. Then, each control can
    be passed a reference to this single instance. For example (not tested):

    Public Class ControlProperties
    Public Property ConnectionString As String
    ...
    End Property
    '
    Public Property Log As LogOps
    ...
    End Property
    ...
    End Class
    '
    Public Class MyControlBaseType
    Inherits UserControl

    Public Property Properties As ControlProperties
    ...
    End Property
    End Class

    ' In the page:
    Protected Sub Page_Load (sender As Object, e As EventArgs)
    ...
    Dim props As ControlProperties = New ControlProperties()
    props.ConnectionString = "..."
    props.Log = Log ' Or whatever
    '
    SetCommonProperties(props, Me.Controls)
    End Sub

    Private Sub SetCommonProperties(props As ControlProperties, ctls As
    ControlCollection)
    For Each ctl As Control In ctls
    If TypeOf ctl Is MyControlBaseType Then
    Dim base As MyControlBaseType = DirectCast(ctl,
    MyControlBaseType)
    base.Properties = props
    End If
    '
    If ctl.HasControls Then
    SetCommonProperties(props, ctl.Controls)
    End If
    Next
    End Sub

    You could also choose to avoid the common base type by getting fancy with
    Reflection. Instead of checking to see if the control is a
    MyControlBaseType, you could check to see if it had a property named
    "Properties" which was of a type which derived from "ControlProperties". You
    would have to use Reflection to set the value of that property, however.

    I hope that helps.
    --
    John Saunders
    johnwsaundersiii at hotmail


    > "John Saunders" wrote:
    >
    > > "Donald Welker" <Donald.WelkerN0$SPAM@N0$SPAM.navy.mil> wrote in message
    > > news:...
    > > > The log object in this case is a set of shim routines to write to the

    NT
    > > event log, so it's not much of a risk at the moment. I'm writing a

    "wizard"
    > > to help build a complex document and have broken up sections into about

    a
    > > dozen web controls, each with it's own edit and display panel. When the
    > > user is done the final document is recorded in a database and presented

    for
    > > printing, so each control is supposed to be smart enough to edit its

    portion
    > > of the draft document and display its fields in the final version. My
    > > original thought was to write one module to communicate with the

    database
    > > and share it throughout, but it occurs to me that the controls will have
    > > different data adapters and don't need access to each others' data --

    but I
    > > need to make sure the connection string is shared.
    > > >
    > > > What I've now done is created a "template" control from which to

    derive
    > > the others, but now the derived controls won't load in the designer:
    > > "Abstract Class" -- do I need to add a reference to the template or can

    I no
    > > longer use the designer?
    > >
    > > As to the connection and/or connection string, you could pass that into

    the
    > > controls. Just add a Connection property of type SqlConnection (or

    whichever
    > > connection type you need).
    > >
    > > As to the "no inherited user controls" problem - that's just another
    > > trade-off with user controls. The designer isn't clever enough to do

    what
    > > you want there. If you used custom controls, you wouldn't have this

    problem,
    > > but you _would_ take longer to get the project done. You can have your

    user
    > > controls all inherit from a base class, but that base class can't do
    > > anything as far as UI goes. I've done this successfully in the past.

    >
     
    John Saunders, Jul 30, 2004
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jeff Rodriguez
    Replies:
    23
    Views:
    1,200
    David Schwartz
    Dec 9, 2003
  2. Replies:
    0
    Views:
    172
  3. Replies:
    0
    Views:
    227
  4. Noel Dolan
    Replies:
    0
    Views:
    274
    Noel Dolan
    Jul 18, 2004
  5. Bitswapper
    Replies:
    5
    Views:
    182
    Prasad, Ramit
    Aug 27, 2013
Loading...

Share This Page