Where FooControl is a UserControl in the folder "controls". So far I have figured the following out:
1) You must use the @Reference directive at the top of the markup page for each control you want to reference this way (adding an entry in web.config/system.web/pages/controls won't work)
2) You don't need to have the @Register directive or an instance of the control on the page.
3) The control needs to have a "ClassName" attribute defined in it's @Control tag. For inline controls, this is already done. For code-behind, you have to add that to the tag in the ascx file (I've tested it) 4) You can't do this from a code-behind file.
It just doesn't work, and complains it can't find the class FooControl ("Compiler Error Message:
CS0246: The type or namespace name 'FooControl' could not be found (are you missing a using directive or an assembly reference?)")
Point 4 is what I'm trying to figure out. I can't put the control in declaritively in the mark-up, and I don't want to have an interface for every control I need. I haven't been able to find any answers for this question, except maybe one article that I
read that said "you can't use code-behind if you want to do this". I'm hoping to get to the bottom of this. I'm hoping some expert out there can give me an answer and tell me a solution. Or at least a definite answer. And if this isn't possible.
Why not? Thanks,
Anthony Aziz
That code should work. If you are not using the type FooControl using the exact namespace and class path (I guess you would call it), then you need to be sure that at the top of the code file, you import the namespace.
For example, if your control path is "~/controls/FooControl.ascx" and your project namespace is Project, then instead of:
FooControl foo = etc.
you must write
Project.controls.FooControl foo = etc.
unless at the top, you include that namespace, like in C# writing:
using Project.controls;
granted, this will only work if you did not change the code-behinds namespace, as Visual Studio automatically gives it the namespace based upon Project name and the folder path to where you had it create the control.
This is caused by changes in the ASP.NET 2.0 compilation model. The new dynamic compilation for pages and user controls has the side-effect of making their types more difficult to reference. The best solution is to create a base class for your control which
exposes the functionality you need, and reference that instead. Have a look at
this article for more info. HTH
Thank you both for replying. Talk about a long article. I'll be sure to look into it in more detail later. I'm going to see if jzimmerman's solution will work first. I have considered creating an interface in App_Code for each control... but that can be
annoying, and perhaps there's another way. I'm just confused as to why the difference between code-behind and inline impacts so heavily on this issue.
As to referencing the control by namespace, I'll be sure to try that (as soon as I get VS up on this slow computer). I haven't put anything in a namespace (perhaps I should?), so you're saying the FQN is <ProjectName>.controls.FooControl ? (I hope this
works for nested folders, as the actual control is ~/controls/reports/ReportForm.ascx. Normally, I wouldn't doubt it, but there's been too many surprises). I'm going to try this out, but one thing I can forsee is not knowing the project name. I'm connected
to localhost (and it's not something I can change, this is the way the development machines are set up here). What would the project name be, then?
Again, Thanks, I welcome more advice and explanations!
it may also depend upon what type of project you are doing. (you mentioned that you have an app_code folder, and i think that app_code folders are only used in web sites, not web apps.)
with a web app, you control source files look something like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace XUCS.code.controls
{
public partial class CourseDisplay : System.Web.UI.UserControl
{
the namespace line is automatically generated to be ProjectNamespace.ParentFolder.ChildFolder
for web site projects, the namespace block is removed, but now the class name (that is, if kept as default) reflects the controls folder path. so all there would be to define the control would be
public partial class Code_Controls_CourseDisplay : System.Web.UI.UserControl
So, if you are using a web site project, then you should already be doing it right, as long as you are sure you are using the full class name on the controls code file.
Instead of referring to your code via a general example, could you possibly post (or email me) the actual code you are using?
WELL, after restarting VS and waiting 20 minutes for it to load (yeah, I know, a new workstation is in the works...), I believe I've got something.
I started with a using clause, then browed through the namespaces IntelliSense brought up. I looked throught the unusualy sounding ones, and found one called "ASP". IntelliSense showed me there were a few classes in there... related to some (but not all)
of my UserControls, and no child namespaces. So I simply put "using ASP", and it worked, at least for my test were the page and the control are in the same directory. Now, to test a more realistic situation.
Sorry jzimmerman, posted before I read your reply. Let me gather the code and post it. I'll have to edit it to take out database and server paths, but the actual code shouldn't be too big an issue.
The project is a Web Site Project, I think. How I opened it, Open Website > IIS > localhost. And I tried the full class name (_controls_reports_ReportForm), but it was the same issue. If I put ClassName="ReportForm" in the markup file, I can reference
it by that name anyways.
The issue was referencing in the code-behind file of an aspx page. I think the namespace was the issue. And I think the ASP namespace only contains controls where you use the <%@ Reference Control="..." %> to reference the file. I'm still testing. Thanks
for the advice, again.
as long as the control is visible in the namespace you referenced, it really shouldn't matter whether the page is in the same folder as the control.
you might want to check the controls that you said were not listed under the namespace, and see which namespace they belong to in their code file, just so you would know for future reference.
I just played around with a few things, and in a new web site project, i could only use controls in the code-behind that were referenced in the aspx markup using the <%@ Reference %> tag.
The ASP namespace you imported must have been written into the control code files, it is not generated by default i dont believe. if you check a control's code that is in that namespace, then it probably has the ASP namespace declaration. The controls
that you noticed were missing probably have not had that namespace added to them yet.
Actually, i think you are right about the ASP namespace thing. I added a reference tag to a page real quick, and the class appeared in the ASP namespace.
Okay, I figured it out (with help to you guys, of course!). The namespace is "ASP" for this website. I don't know why, but it is. I'll give a little background. I started at this company in October, and I didn't start working on the web application until
February. The software is a subscriber based web application spread across multiple server farms. It was originally done in classic ASP, and only a few new parts are being coded in ASP.NET (my Crystal Reports module is one of them). Everyone has a copy of
the webapp in there local IIS folder, so I connect to the website under localhost IIS. It has a lot of .asp and other files, so it's not a deployed project. I save the pages I work on, then browse to http://localhost/apage.aspx to test.
There is no namespace in the code-behind files. From your post it sounds likes the ASP namespace is the default namespace for controls referenced. Anyways, this works for me. I'll post the relevant code. You won't be able to run it, there's some framework
objects there that are just to complicated to post.
using System; using System.Collections; using System.Configuration; using System.Data; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts;
using System; using System.Collections; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts;
public partial class controls_reports_ScheduledReports : System.Web.UI.UserControl { public event CommandEventHandler EditSchedule; public event CommandEventHandler DeletedSchedule;
aazizorg
Member
3 Points
7 Posts
Using the class of a user control in code-behind
May 21, 2009 09:06 PM|LINK
I'm having an issue where I want to be able to reference the class of a UserControl in a page, like this
FooControl foo = (FooControl) LoadControl("~/controls/FooControl.ascx"); foo.Bar= "Bazbazbaz"; this.Controls.Add(foo);Where FooControl is a UserControl in the folder "controls". So far I have figured the following out:
1) You must use the @Reference directive at the top of the markup page for each control you want to reference this way (adding an entry in web.config/system.web/pages/controls won't work)
2) You don't need to have the @Register directive or an instance of the control on the page.
3) The control needs to have a "ClassName" attribute defined in it's @Control tag. For inline controls, this is already done. For code-behind, you have to add that to the tag in the ascx file (I've tested it)
4) You can't do this from a code-behind file. It just doesn't work, and complains it can't find the class FooControl ("Compiler Error Message: CS0246: The type or namespace name 'FooControl' could not be found (are you missing a using directive or an assembly reference?)")
Point 4 is what I'm trying to figure out. I can't put the control in declaritively in the mark-up, and I don't want to have an interface for every control I need. I haven't been able to find any answers for this question, except maybe one article that I read that said "you can't use code-behind if you want to do this". I'm hoping to get to the bottom of this. I'm hoping some expert out there can give me an answer and tell me a solution. Or at least a definite answer. And if this isn't possible. Why not? Thanks,
Anthony Aziz
jzimmerman20...
Member
503 Points
183 Posts
Re: Using the class of a user control in code-behind
May 22, 2009 02:20 AM|LINK
That code should work. If you are not using the type FooControl using the exact namespace and class path (I guess you would call it), then you need to be sure that at the top of the code file, you import the namespace.
For example, if your control path is "~/controls/FooControl.ascx" and your project namespace is Project, then instead of:
FooControl foo = etc.
you must write
Project.controls.FooControl foo = etc.
unless at the top, you include that namespace, like in C# writing:
using Project.controls;
granted, this will only work if you did not change the code-behinds namespace, as Visual Studio automatically gives it the namespace based upon Project name and the folder path to where you had it create the control.
booler
Star
14342 Points
2205 Posts
Re: Using the class of a user control in code-behind
May 22, 2009 11:21 AM|LINK
This is caused by changes in the ASP.NET 2.0 compilation model. The new dynamic compilation for pages and user controls has the side-effect of making their types more difficult to reference. The best solution is to create a base class for your control which exposes the functionality you need, and reference that instead. Have a look at this article for more info. HTH
aazizorg
Member
3 Points
7 Posts
Re: Using the class of a user control in code-behind
May 22, 2009 01:01 PM|LINK
Thank you both for replying. Talk about a long article. I'll be sure to look into it in more detail later. I'm going to see if jzimmerman's solution will work first. I have considered creating an interface in App_Code for each control... but that can be annoying, and perhaps there's another way. I'm just confused as to why the difference between code-behind and inline impacts so heavily on this issue.
As to referencing the control by namespace, I'll be sure to try that (as soon as I get VS up on this slow computer). I haven't put anything in a namespace (perhaps I should?), so you're saying the FQN is <ProjectName>.controls.FooControl ? (I hope this works for nested folders, as the actual control is ~/controls/reports/ReportForm.ascx. Normally, I wouldn't doubt it, but there's been too many surprises). I'm going to try this out, but one thing I can forsee is not knowing the project name. I'm connected to localhost (and it's not something I can change, this is the way the development machines are set up here). What would the project name be, then?
Again, Thanks, I welcome more advice and explanations!
jzimmerman20...
Member
503 Points
183 Posts
Re: Using the class of a user control in code-behind
May 22, 2009 02:05 PM|LINK
it may also depend upon what type of project you are doing. (you mentioned that you have an app_code folder, and i think that app_code folders are only used in web sites, not web apps.)
with a web app, you control source files look something like this:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace XUCS.code.controls { public partial class CourseDisplay : System.Web.UI.UserControl {the namespace line is automatically generated to be ProjectNamespace.ParentFolder.ChildFolder
for web site projects, the namespace block is removed, but now the class name (that is, if kept as default) reflects the controls folder path. so all there would be to define the control would be
public partial class Code_Controls_CourseDisplay : System.Web.UI.UserControl
So, if you are using a web site project, then you should already be doing it right, as long as you are sure you are using the full class name on the controls code file.
Instead of referring to your code via a general example, could you possibly post (or email me) the actual code you are using?
aazizorg
Member
3 Points
7 Posts
Re: Using the class of a user control in code-behind
May 22, 2009 02:17 PM|LINK
WELL, after restarting VS and waiting 20 minutes for it to load (yeah, I know, a new workstation is in the works...), I believe I've got something.
I started with a using clause, then browed through the namespaces IntelliSense brought up. I looked throught the unusualy sounding ones, and found one called "ASP". IntelliSense showed me there were a few classes in there... related to some (but not all) of my UserControls, and no child namespaces. So I simply put "using ASP", and it worked, at least for my test were the page and the control are in the same directory. Now, to test a more realistic situation.
I'll post more when I find out more.
aazizorg
Member
3 Points
7 Posts
Re: Using the class of a user control in code-behind
May 22, 2009 02:27 PM|LINK
Sorry jzimmerman, posted before I read your reply. Let me gather the code and post it. I'll have to edit it to take out database and server paths, but the actual code shouldn't be too big an issue.
The project is a Web Site Project, I think. How I opened it, Open Website > IIS > localhost. And I tried the full class name (_controls_reports_ReportForm), but it was the same issue. If I put ClassName="ReportForm" in the markup file, I can reference it by that name anyways.
The issue was referencing in the code-behind file of an aspx page. I think the namespace was the issue. And I think the ASP namespace only contains controls where you use the <%@ Reference Control="..." %> to reference the file. I'm still testing. Thanks for the advice, again.
jzimmerman20...
Member
503 Points
183 Posts
Re: Using the class of a user control in code-behind
May 22, 2009 02:32 PM|LINK
as long as the control is visible in the namespace you referenced, it really shouldn't matter whether the page is in the same folder as the control.
you might want to check the controls that you said were not listed under the namespace, and see which namespace they belong to in their code file, just so you would know for future reference.
jzimmerman20...
Member
503 Points
183 Posts
Re: Using the class of a user control in code-behind
May 22, 2009 02:41 PM|LINK
I just played around with a few things, and in a new web site project, i could only use controls in the code-behind that were referenced in the aspx markup using the <%@ Reference %> tag.
The ASP namespace you imported must have been written into the control code files, it is not generated by default i dont believe. if you check a control's code that is in that namespace, then it probably has the ASP namespace declaration. The controls that you noticed were missing probably have not had that namespace added to them yet.Actually, i think you are right about the ASP namespace thing. I added a reference tag to a page real quick, and the class appeared in the ASP namespace.
aazizorg
Member
3 Points
7 Posts
Re: Using the class of a user control in code-behind
May 22, 2009 03:08 PM|LINK
Okay, I figured it out (with help to you guys, of course!). The namespace is "ASP" for this website. I don't know why, but it is. I'll give a little background. I started at this company in October, and I didn't start working on the web application until February. The software is a subscriber based web application spread across multiple server farms. It was originally done in classic ASP, and only a few new parts are being coded in ASP.NET (my Crystal Reports module is one of them). Everyone has a copy of the webapp in there local IIS folder, so I connect to the website under localhost IIS. It has a lot of .asp and other files, so it's not a deployed project. I save the pages I work on, then browse to http://localhost/apage.aspx to test.
There is no namespace in the code-behind files. From your post it sounds likes the ASP namespace is the default namespace for controls referenced. Anyways, this works for me. I'll post the relevant code. You won't be able to run it, there's some framework objects there that are just to complicated to post.
Here's the page:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ReferencingControlsIncodeBehind.aspx.cs" Inherits="_test_ReferencingControlsIncodeBehind" %> <%@ Reference Control="~/_test/WebUserControlInline.ascx" %> <%@ Reference Control="~/_test/WebUserControlCodebehind.ascx" %> <%@ Reference Control="~/controls/reports/ScheduledReports.ascx" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <div> <asp:PlaceHolder ID="placeholder" runat="server"></asp:PlaceHolder> </div> </form> </body> </html>And the code behind:
And the ReportScheduler.ascx
And it's code behind: