472,126 Members | 1,429 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,126 software developers and data experts.

User-control with property accessors == null references

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.H andler);
this.sqlDataSource.SelectCommand = value;
}
get
{
// again, see below.
this.InitializeAsUserControl(HttpContext.Current.H andler);
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.

Aug 1 '06 #1
2 1992
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" <st******@yahoo.comwrote in message
news:11**********************@75g2000cwc.googlegro ups.com...
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.H andler);
this.sqlDataSource.SelectCommand = value;
}
get
{
// again, see below.
this.InitializeAsUserControl(HttpContext.Current.H andler);
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.

Aug 1 '06 #2
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" <st******@yahoo.comwrote in message
news:11**********************@75g2000cwc.googlegro ups.com...
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.H andler);
this.sqlDataSource.SelectCommand = value;
}
get
{
// again, see below.
this.InitializeAsUserControl(HttpContext.Current.H andler);
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.
Aug 3 '06 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

60 posts views Thread by Fotios | last post: by
3 posts views Thread by zlst | last post: by
3 posts views Thread by Jiho Han | last post: by
17 posts views Thread by Alphonse Giambrone | last post: by
6 posts views Thread by Andrew Chalk | last post: by
1 post views Thread by Carlettus | last post: by
4 posts views Thread by Scott M. | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.