User-control with property accessors == null references

Discussion in 'ASP .Net' started by Mark, Aug 1, 2006.

  1. Mark

    Mark Guest

    Hi.

    I am making a user control right now, and it looks something like this:

    <script runat="server">
    public string SelectCommand
    {
    set
    {
    // see below for why the following line is here.
    this.InitializeAsUserControl(HttpContext.Current.Handler);
    this.sqlDataSource.SelectCommand = value;
    }
    get
    {
    // again, see below.
    this.InitializeAsUserControl(HttpContext.Current.Handler);
    return this.sqlDataSource.SelectCommand;
    }
    }
    </script>

    <asp:SqlDataSource runat="server" />
    <%-- etc... repeat about 9 times --%>


    So then, on my page I put something like this:

    <asdf:MyControl SelectCommand="SELECT whatever FROM something"
    runat="server" />

    Now, the commented lines are there because, if I didn't have them,
    ASP.NET would construct MyControl and immediately try and set
    SelectCommand. This would happen before MyControl built its child
    controls.

    I'm wondering, is there a better way to do this, other than to
    construct all the child controls manually in the constructor?
    (Actually, I can't even declare the constructor for a user control, so
    I'd have to switch to a custom control. And that is a problem for
    various reasons I'd rather not get into.)

    I could save the property settings in private member variables, but
    that's really messy with about 10-15 of them, and I'd have to
    arbitrarily pick a point where I "move over" the settings. (Probably
    OnPreRender) And on top of that, there are read-only properties (i.e.
    collections) that I expose this way, so it would take a lot of work to
    get that to work right.

    In a normal control, I guess I would call EnsureChildControls in a
    place like this, but I don't have that option. InitializeAsUserControl
    seems to be the closest thing available, but I don't like it because I
    have to access HttpContext.Current.Handler, and so it doesn't seem like
    it was designed for this.

    Am I just trying to do something the wrong way?

    Thanks.
    Mark, Aug 1, 2006
    #1
    1. Advertising

  2. You are not creating a user control, you are creating a data access layer,
    business layer and UI element wrapped into on ASCX page. IT is a clever
    idea, but you end up with a couple of problems.

    1. Your database is exposed, at least partially, in your pages.
    2. An error in coding is not discovered until the page is run

    Technically, UI controls should paint the page. They should not care about
    SQL statements, as that is a business concern.

    In your case, you could tweak the page and get generic data to bind. But,
    the design is not a wise direction and I would consider looking at the more
    common patterns presented in Microsoft documentation. It will be more
    maintainable in the long run.

    --
    Gregory A. Beamer
    MVP; MCP: +I, SE, SD, DBA

    *************************************************
    Think outside of the box!
    *************************************************
    "Mark" <> wrote in message
    news:...
    > Hi.
    >
    > I am making a user control right now, and it looks something like this:
    >
    > <script runat="server">
    > public string SelectCommand
    > {
    > set
    > {
    > // see below for why the following line is here.
    > this.InitializeAsUserControl(HttpContext.Current.Handler);
    > this.sqlDataSource.SelectCommand = value;
    > }
    > get
    > {
    > // again, see below.
    > this.InitializeAsUserControl(HttpContext.Current.Handler);
    > return this.sqlDataSource.SelectCommand;
    > }
    > }
    > </script>
    >
    > <asp:SqlDataSource runat="server" />
    > <%-- etc... repeat about 9 times --%>
    >
    >
    > So then, on my page I put something like this:
    >
    > <asdf:MyControl SelectCommand="SELECT whatever FROM something"
    > runat="server" />
    >
    > Now, the commented lines are there because, if I didn't have them,
    > ASP.NET would construct MyControl and immediately try and set
    > SelectCommand. This would happen before MyControl built its child
    > controls.
    >
    > I'm wondering, is there a better way to do this, other than to
    > construct all the child controls manually in the constructor?
    > (Actually, I can't even declare the constructor for a user control, so
    > I'd have to switch to a custom control. And that is a problem for
    > various reasons I'd rather not get into.)
    >
    > I could save the property settings in private member variables, but
    > that's really messy with about 10-15 of them, and I'd have to
    > arbitrarily pick a point where I "move over" the settings. (Probably
    > OnPreRender) And on top of that, there are read-only properties (i.e.
    > collections) that I expose this way, so it would take a lot of work to
    > get that to work right.
    >
    > In a normal control, I guess I would call EnsureChildControls in a
    > place like this, but I don't have that option. InitializeAsUserControl
    > seems to be the closest thing available, but I don't like it because I
    > have to access HttpContext.Current.Handler, and so it doesn't seem like
    > it was designed for this.
    >
    > Am I just trying to do something the wrong way?
    >
    > Thanks.
    >
    Cowboy \(Gregory A. Beamer\), Aug 1, 2006
    #2
    1. Advertising

  3. Mark

    Mark Guest

    Thanks for the response. Definitely a little beyond what I expected.
    I'm curious, could you give an example of how to improve? I figured
    that using an SqlDataSource along with a DataGrid went along pretty
    well with MSDN examples. Are you suggesting a more layered approach,
    perhaps using an ObjectDataSource instead?

    However, I think I have another example that you would not object to:

    <%@ Control Language="C#" ClassName="DateInput" %>

    <script runat="server">
    public string Label
    {
    get
    {
    return this.label.Text;
    }
    set
    {
    this.label.Text = value;
    }
    }

    public string Value
    {
    get
    {
    if (this.year.Text == ""
    && this.month.Text == ""
    && this.day.Text == "")
    {
    return "";
    }
    return new DateTime(int.Parse(this.year.Text),
    int.Parse(this.month.Text),
    int.Parse(this.day.Text)).ToString();
    }
    set
    {
    if (value == "")
    {
    this.month.Text = "";
    this.day.Text = "";
    this.year.Text = "";
    }
    else
    {
    DateTime dateTime = DateTime.Parse(value);
    this.month.Text = dateTime.Month.ToString();
    this.day.Text = dateTime.Day.ToString();
    this.year.Text = dateTime.Year.ToString();
    }
    }
    }
    </script>

    <div class="field">
    <asp:Label ID="label" AssociatedControlID="month" runat="server" />
    <asp:TextBox ID="month" CssClass="mm" MaxLength="2" runat="server" />
    /
    <asp:TextBox ID="day" CssClass="dd" MaxLength="2" runat="server" />
    /
    <asp:TextBox ID="year" CssClass="yyyy" MaxLength="4" runat="server" />
    </div>

    Now the weird part is, this does not require that I call
    InitializeAsUserControl() ever! I can do this in any page:

    <ct:DateInput Value="2006-01-01" runat="server" />

    And it does not give me trouble. I might have been premature in
    identifying this as the solution to my other problem.

    Any ideas?

    Thanks again,

    Mark

    Cowboy (Gregory A. Beamer) wrote:
    > You are not creating a user control, you are creating a data access layer,
    > business layer and UI element wrapped into on ASCX page. IT is a clever
    > idea, but you end up with a couple of problems.
    >
    > 1. Your database is exposed, at least partially, in your pages.
    > 2. An error in coding is not discovered until the page is run
    >
    > Technically, UI controls should paint the page. They should not care about
    > SQL statements, as that is a business concern.
    >
    > In your case, you could tweak the page and get generic data to bind. But,
    > the design is not a wise direction and I would consider looking at the more
    > common patterns presented in Microsoft documentation. It will be more
    > maintainable in the long run.
    >
    > --
    > Gregory A. Beamer
    > MVP; MCP: +I, SE, SD, DBA
    >
    > *************************************************
    > Think outside of the box!
    > *************************************************
    > "Mark" <> wrote in message
    > news:...
    > > Hi.
    > >
    > > I am making a user control right now, and it looks something like this:
    > >
    > > <script runat="server">
    > > public string SelectCommand
    > > {
    > > set
    > > {
    > > // see below for why the following line is here.
    > > this.InitializeAsUserControl(HttpContext.Current.Handler);
    > > this.sqlDataSource.SelectCommand = value;
    > > }
    > > get
    > > {
    > > // again, see below.
    > > this.InitializeAsUserControl(HttpContext.Current.Handler);
    > > return this.sqlDataSource.SelectCommand;
    > > }
    > > }
    > > </script>
    > >
    > > <asp:SqlDataSource runat="server" />
    > > <%-- etc... repeat about 9 times --%>
    > >
    > >
    > > So then, on my page I put something like this:
    > >
    > > <asdf:MyControl SelectCommand="SELECT whatever FROM something"
    > > runat="server" />
    > >
    > > Now, the commented lines are there because, if I didn't have them,
    > > ASP.NET would construct MyControl and immediately try and set
    > > SelectCommand. This would happen before MyControl built its child
    > > controls.
    > >
    > > I'm wondering, is there a better way to do this, other than to
    > > construct all the child controls manually in the constructor?
    > > (Actually, I can't even declare the constructor for a user control, so
    > > I'd have to switch to a custom control. And that is a problem for
    > > various reasons I'd rather not get into.)
    > >
    > > I could save the property settings in private member variables, but
    > > that's really messy with about 10-15 of them, and I'd have to
    > > arbitrarily pick a point where I "move over" the settings. (Probably
    > > OnPreRender) And on top of that, there are read-only properties (i.e.
    > > collections) that I expose this way, so it would take a lot of work to
    > > get that to work right.
    > >
    > > In a normal control, I guess I would call EnsureChildControls in a
    > > place like this, but I don't have that option. InitializeAsUserControl
    > > seems to be the closest thing available, but I don't like it because I
    > > have to access HttpContext.Current.Handler, and so it doesn't seem like
    > > it was designed for this.
    > >
    > > Am I just trying to do something the wrong way?
    > >
    > > Thanks.
    > >
    Mark, Aug 3, 2006
    #3
    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. Replies:
    5
    Views:
    26,518
    Mike Schilling
    Mar 29, 2006
  2. =?Utf-8?B?U2FtIE1hcnRpbg==?=

    null references in my user control!!

    =?Utf-8?B?U2FtIE1hcnRpbg==?=, Apr 27, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    7,186
    =?Utf-8?B?U2FtIE1hcnRpbg==?=
    Apr 27, 2006
  3. Vincent RICHOMME

    NULL pointer and null references

    Vincent RICHOMME, Jan 15, 2006, in forum: C++
    Replies:
    3
    Views:
    306
  4. Sam Samnah

    Composite controls and Property Accessors

    Sam Samnah, Jun 27, 2005, in forum: ASP .Net Building Controls
    Replies:
    0
    Views:
    114
    Sam Samnah
    Jun 27, 2005
  5. Harry Higbie

    User control property reference gives null error

    Harry Higbie, Jul 15, 2004, in forum: ASP .Net Web Controls
    Replies:
    0
    Views:
    132
    Harry Higbie
    Jul 15, 2004
Loading...

Share This Page