User-control with property accessors == null references

M

Mark

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.
 
C

Cowboy \(Gregory A. Beamer\)

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!
*************************************************
 
M

Mark

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
 

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

No members online now.

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,227
Latest member
Daniella65

Latest Threads

Top