ASP.NET- Instantiate a Web User Control in App_Code class - asp.net

Files:
Website\Controls\map.ascx
Website\App_Code\map.cs
I'd like to create a strongly typed instance of map.ascx in map.cs
Normally, in an aspx, you would add a <%Register... tag to be able to instantiate in codebehind. Is this possible in an app_code class?
I'm using .NET 3.5/Visual Studio 2008
Thanks!

Normally, I'd do something like this (assuming your type is "Map" and that you have the appropriate "Inherits" declaration in your .ascx file):
Map map = (Map)LoadControl("~/Controls/map.ascx");

Is there a map.ascx.cs file in Website\Controls? If so, move it to App_Code. Note you may have to update the CodeFile attribute in the .ascx file to ~\App_Code\map.ascx.cs.
Alternatively, since the control is a partial class, you could just create the code in ~\App_Code\map.cs as:
public partial class controls_Map : UserControl
{
protected void Page_Load( object sender, EventArgs e )
{
...code here....
}
}
And remove all the methods from the map.ascx.cs file in the controls directory.

Related

Cast ascx within App_Code class

I have an ascx which I want to load and cast from a class sitting within App_Code. I can't get it to work from the App_Code class, although I can get it to work from an aspx page.
The ASPX page technique works fine with the following code:
pc = LoadControl("enquirycapture.ascx");
((ASP.enquirycapture_ascx)pc).CustomProperty = customObject;
(Note: I have the following in the aspx page:)
<%# Reference VirtualPath="~/enquirycapture.ascx" %>
However, when I try casting the control from within the App_Code class then it can't 'see' the ascx class, and therefore I am unable to cast to it to set the custom properties(I can load it, but not cast it). I don't know how to replicate the <% Reference...> thing from within the App_Code class. Anyone know how I can reference (and thus cast) my ascx from the App_Code class? Thanks.
App_Code compiles to a seperate assembly that can't reference types in a CodeFile.
But you can add interface/base class to your App_Code folder that identifies the custom properties and methods that you intend to implement in your usercontrol:
public class EnquiryCaptureBase : System.Web.UI.UserControl
{
public object CustomProperty { get; set; }
}
and then
public partial class EnquiryCapture : EnquiryCaptureBase
{
}
and finally somewhere in App_Code:
pc = LoadControl("enquirycapture.ascx");
((EnquiryCaptureBase)pc).CustomProperty = customObject;

Type '_Default' already defines a member called 'Page_Load' with the same parameter types

I've been renaming some classes and packages in my aspx project and now i have this error:
"Type '_Default' already defines a member called 'Page_Load' with the
same parameter types"
I have two aspx pages. In the default.aspx codebehind i see:
Default.aspx:
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="_Default" %>
Default.aspx.cs:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
//error line under 'Page_Load'
}
search.aspx:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="search.aspx.cs" Inherits="_Default" %>
search.aspx.cs:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
}
Every new ASPX page I add to my project is automaticly added to some namespace.
I've tried changing the inherits attribuut. But i couldn't find a way to fix this error and to get rid of the namespace.
I'm using Visual Studio 2010.
Every page you add is automatically configured to namespace depending on your folder structure. I don't see enough code and structure, but are you sure, that you don't have the Page_Load defined twice? At least the error message says so. Does it behave same even when you use different class name than _Default ?
After edits:
Yea, there we go. You define same class (_Default) in both Default.aspx and Search.aspx ... You should rename your classes according to conventions. ie: use class "Default" in your Default.aspx and use class "Search" in your Search.aspx
Double click the error, temporarily rename the Page_Load to something else. Go down into the body of the function and type Page_Load. Press F12. That will get you to the place where you have second Page_Load method already defined. You'll probably see that it's in another partial _Default class in the same namespace.
Just to add up a specific case.
You can come across to this situation when you convert Web Site into Web Application.
When your project in form of Web Site, when you add for example Default.aspx into two different folders they both created without namespace with the same class name. Both declared partial and it is just fine. But when you convert into Web Application and try to build they start conflicting as they are in the same namespace, declared partial and have their own Page_Load methods.
One of the solutions can be giving distinct class names or encapsulating into different namespaces in accordance with the folder structure.
Since your class is public partial class _Default it's probably some naming that is causing the problem. Try to identify the other part(s) of _Default. Since it's a partial class you're able to have as many partials as you want.. Problem is probably that Page_Load is defined in one of those.
Below follows issues I have encountered when copying files into my solution, clicking on the reported error or on "Go to Definition" mislead me to spot the cause. The hint is one line above..... !
I'm exposing the Problem AND how I finally Resolved it.
Errors when building the application:
Error 1 Type 'Solution1.Web.yourABC' already defines a member
called 'Page_Load' with the same parameter types
C:\\trunk\Solution1.Web\yourABC.aspx.cs 12 24
Solution1.Web
Error 2 Type 'Solution1.Web.yourABC' already defines a member
called 'Page_Load' with the same parameter types
C:\\trunk\Solution1.Web\GuideABT.aspx.cs 12 24
Solution1.Web
How the problem arose:
I copy/pasted a file .aspx in the same solution to make a new file.
C#: Error like below started to appear; worst other misleading errors started to impact the application at runtime:
* Be aware that error 1 IS NOT an error it is CORRECT, as it is the source code
Error 1 Type 'Solution1.Web.yourABC' already defines a member called 'Page_Load' with the same parameter types C:\<folderpath>\trunk\Solution1.Web\yourABC.aspx.cs 12 24 Solution1.Web
Error 2 Type 'Solution1.Web.yourABC' already defines a member called 'Page_Load' with the same parameter types C:\<folderpath>\trunk\Solution1.Web\GuideABT.aspx.cs 12 24 Solution1.Web
Both classes "Page_Load" are empty, normally they are generated automatically by the Visual Studio Engine
Solution:
Change the .cs file of the newly create/pasted aspx page to reflect the page name after the Class "name". In this case "GuideABT.aspx" is the new pasted & renamed aspx file:
Correction on Error 1: NO CORRECTION NEEDED as it is the copied from file. MAKE SURE THAT the name of the file and the name of the class reference ARE the same in the .cs files:
File name yourABC.aspx, check the .cs extension files:
namespace Solution1.Web
{
public partial class yourABC : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
Correction on Error 2: MODIFY the pasted file. Correct the CLASS NAME to reflect the name of the .aspx file.
File name GuideABT.aspx, check the .cs extension files:
ORIGINAL code in .cs
namespace Solution1.Web
{
public partial class *yourABC* : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
CORRECTED this code in .cs TO
namespace Solution1.Web
{
public partial class **GuideABT** : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
Issue RESOLVED.
Cheers.

asp.net use class object on form

I am creating an object at server side of an aspx (test.cs) page from a class (asp.net 2.0 C#)
public partial class Vendor_VendorUsedTicketsPopup : System.Web.UI.Page
{
ReportInvoice _objReportInvoice = new ReportInvoice();
protected void Page_Load(object sender, EventArgs e)
{
_objReportInvoice.ReportId = 1;
}
}
as you see above before Page Load I am creating a new ReportInvoice object and on page load I am setting property ReportId to 1
On test.aspx I want to use the ReportId value bu using the _objReportInvoice object like below
<div><% _objReportInvoice.ReportId; %></div>
But when I build the site I get the error
The name '_objReport' does not exist in the current context
I know that I can create a public integer for ReportId above Page_Load and use it on aspx page. That works fine , but I want to use class object properties on aspx page.
What is the way of doing sth like that ?
Thanks...
You need a = sign in there to print it to the page:
<div><%= _objReportInvoice.ReportId; %></div>
However, I would suggest just using a Literal or Label control there and then setting it's text to the ReportID property in the code behind. Inline code like that can make your HTML messy.
Remember that your .ASPX markup page inherits from the codebehind class.
This means that unless you declare your field as protected or public, the .aspx will not have access to your field.
You need to add an access modifier to your field to make it non-private.

Dynamically Load a user control (ascx) in a asp.net website

I am trying to dynamically load a user control in an asp.web site. However due to how asp.net websites projects are setup (I think), I am not able to access reach the type definition of the user control.
I get a message saying that my class HE_ContentTop_WebControl1 is: he type or namespace name 'HE_ContentTop_WebControl1' could not be found (are you missing a using directive or an assembly reference?)
Any idea how this could be made to work ? I have attempted using namespace but it seems to me that asp.net websites are not designed to work with namespaces by default. I would be interested in a non namespace approach.
TIA
public partial class HE_Default :
System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e)
{
var control = (HE_ContentTop_WebControl1)Page.LoadControl("~/ContentTop/WebControl1.ascx");
}
}
Assuming the control exists in the same assembly as your web project, you need to add a reference directive in your .aspx file,
e.g:
<%# Reference Control="~/Controls/WebControl1.ascx">
Keep in mind it often takes a few minutes (or sometimes a build) for IntelliSense to pick this up.
It can easily be done using namespaces. Here's an example:
WebControl1.ascx:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="WebControl1.ascx.cs" Inherits="MyUserControls.WebControl1" %>
Notice that Inherits references the namespace (MyUserControls), and not just the class name (WebControl1)
WebControl1.ascx.cs:
namespace MyUserControls
{
public partial class WebControl1 : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
Notice that the class have been included in the namespace MyUserControls
Default.aspx.cs:
using MyUserControls;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var control = (WebControl1) Page.LoadControl("~/WebControl1.ascx");
}
}
This approach potentially allow you to redistribute your user controls (or keep them in a separate project) without the hassle of referencing them in your .aspx files.
Namespaces are not supported under the website model. As such, I could not get any of the solutions proposed to work. However, there is a solution. Create an interface and place it into app code and then implement the interface in the user control. You can cast to the interface and it works.
The subject of this post is a bit misleading. If you just want to add a control dynamically, you will not have to reference the control and therefore you can just add it with something simple like:
protected void Page_Load(object sender, EventArgs e)
{
Page.Controls.Add(Page.LoadControl("~/MyControl.ascx"));
}
without any namespace hassel.
the reference is not enough using
<%# Reference Control="~/Controls/WebControl1.ascx">
in the aspx file is just one part of the answer.
you need also to add the calssName in the User Control aspx file
<%# Control ClassName="WebControl1" Language="C#" AutoEventWireup="true" CodeFile="WebControl1.ascx.cs" Inherits="AnySpaceName.DateSelector" %>
and then you can use the userontrol in your aspx file
AnySpaceName.WebControl1 WC = (AnySpaceName.WebControl1)Page.LoadControl("~/WebControl1.ascx");
Casting the user control this way may create many problems .my approach is to create a class (say control Class) put all the properties and method you need for casting in it and inherit this class from System.Web.UI.UserControl .Then in your user cotrol code file instead of System.Web.UI.UserControl user this control class .
now when ever you need casting, cast with this class only . it will be light casting as well.

ASP.NET UserControl Inheritance

I have a UserControl that is working fine. It is declared like this.
public partial class DynamicList : System.Web.UI.UserControl
{
protected static BaseListController m_GenericListController = null;
public DynamicList()
{
m_GenericListController = new GenericListController(this);
}
}
Now I want to override this control so I can change some of the properties. I have created a class like this.
public partial class JobRunningList : DynamicList
{
public JobRunningList()
{
m_GenericListController = new JobListController(this);
(m_GenericListController as GenericListController).ModuleId = 14;
}
}
It appears that the controls in the DynamicList are not getting created though when I use the JobRunningList control now causing predictably bad results. The DynamicList UserControl has a ListView on it and a few other controls. It appears these are not created when using the JobRunningList. Is there any secret to this?
The boring workaround would be to make JobRunningList as plain old user control that contains a DynamicList and just sets the properties of the inner control in its OnLoad. That's awkward if DynamicList has many other properties that you want to access from the page though, as JobRunningList would have to define matching properties of its own. Getting back to the inheritance approach, then...
The DynamicList class just contains the code behind logic, so what you're doing works nicely if you want the second control to reuse the logic behind the first but provide a new UI of its own.
The markup in your .ascx file gets compiled into another class that inherits DynamicList, so if you can get your JobRunningList class to inherit that class instead of DynamicList, you'll get the result you want. This class gets a default name derived from the filename, but you can avoid guessing that by setting a ClassName in the control directive to use instead of the automatic name.
Take a simple base control like
<%# Control Language="C#" AutoEventWireup="true"
CodeFile="HelloControl.ascx.cs" Inherits="HelloControlBase"
ClassName="MyControls.HelloControl" %>
Hello <%= Name %>
with an unexciting code-behind like
public partial class HelloControlBase : System.Web.UI.UserControl
{
public string Name
{
get;
set;
}
}
Now we want to override the Name property in a new control. First we need HelloAlice.ascx
<%# Control Language="C#" AutoEventWireup="true"
CodeFile="HelloAliceControl.ascx.cs"
Inherits="HelloAliceControl" %>
Not much to see here, since we're leaving all the work to the original ascx. Now in the code-behind,
public partial class HelloAliceControl : MyControls.HelloControl
{
protected void Page_Load(object sender, EventArgs e)
{
this.Name = "Alice";
}
}
We just inherit MyControls.HelloControl and set the Name property, and it looks like we're done.
The problem is knowing when MyControls.HelloControl is visible. As long as your derived control is in the same directory as the parent control you'll probably be OK, otherwise it's quite easy to run into build errors complaining that the class doesn't exist because the parent control hasn't been compiled yet.
If I understand correctly, you want the interface to be the same. In that case, I would create some properties instead. Perhaps just a simple enumeration i.e. ListType.

Resources