Extending usercontrol, Inner controls not initialized if declared on ascx page - c#

The Usercontrol I am creating is made up of 3 files as expected (ascx, ascx.cs, and ascx.designer.cs)
My Problem :
Controls created in the aspx page ( asp:Button runat="server" id="mybutton" />) are not being initialized properly, such that attaching to the 'Load' event, and trying to use button, results in a null object exception
I suspect this is a Visual Studio problem, either weird bug or unusal setting, but it wouldn't surprise me if I'm doing something silly.
My attempted work-a-arounds
I've copied another working User control from a different project into this project in visual studio and it too does not work (controls defined in ascx page are null in load event in code behind page, though they work fine where I copied them from)
I'm using the 'CreateChildControls()' method, as I've done in some other composite controls, but then everything is still null in the load and init events
I've created a seperate solution and project file, and added all the files and references, but still, this does not help the situation.
It appears to me that the 'page life cycle' (control life cycle?) is not initializing the controls properly for some reason, but cant see why, please someone help.
Posting my code as request :
PersonalDetails.aspx
<cwpEditControl:PersonalDetails runat="server" id="edtPersonalDetails" />
PersonalDetails.ascx
<%# Control Language="C#" CodeBehind="PersonalDetails.ascx.cs" Inherits="company.web.CustomerWebPortal.controls.edit.PersonalDetails" %>
<asp:Button runat="server" ID="myTestButton" />
PersonalDetails.ascx.cs
public PersonalDetails()
{
this.Load += new EventHandler(PersonalDetails_Load);
}
void PersonalDetails_Load(object sender, EventArgs e)
{
this.myTestButton.Text = "Submit"; //this line creates an exception!
}
PersonalDetails.ascx.designer.cs
protected global::System.Web.UI.WebControls.Button myTestButton;

I have fixed my problem by adding to the web.config file, basically 'registering' my custom control across the entire web application I am creating :
<pages>
<controls>
<add tagPrefix="scottgu" src="~/Controls/Header.ascx" tagName="header"/>
<add tagPrefix="scottgu" src="~/Controls/Footer.ascx" tagName="footer"/>
<add tagPrefix="ControlVendor" assembly="ControlVendorAssembly"/>
</controls>
</pages>
link explaining the additions to the web.config file (please note this article does not address my problem directly)
http://weblogs.asp.net/scottgu/archive/2006/11/26/tip-trick-how-to-register-user-controls-and-custom-controls-in-web-config.aspx
I dont personally feel the 'site wide' declaration of my custom control should be required, but it fixes the problem so I'm using it, but would still like to me enlightened as to the reason why it is required to be done that way.

Related

ASP.NET Web Forms: Use same tagPrefix for web controls from different namespaces

I've registered two namespaces in Web.config like this:
<add tagPrefix="a" assembly="WebApplication1" namespace="WebFormsApplication1.Controls1" />
<add tagPrefix="a" assembly="WebApplication1" namespace="WebFormsApplication1.Controls2" />
I'm using them like this in an .aspx page:
<a:WebCustomControl1 ID="Control1" runat="server"></a:WebCustomControl1>
<a:WebCustomControl2 ID="Control2" runat="server"></a:WebCustomControl2>
Here's the (broken) .designer.cs file VS generates for that page (notice that it uses Controls2 namespace for both controls, although Control1 lays in Controls1 namespace):
protected global::WebFormsApplication1.Controls2.WebCustomControl1 Control1;
protected global::WebFormsApplication1.Controls2.WebCustomControl2 Control2;
It looks like the second <add in Web.config is overwriting the first one.
I want it to append rather than overwrite, is it possible?
I guess there are other alternatives as well:
Put everything in a single namespace
Use an unique tagPrefix for each namespace
But they are not cool since we have about a hujilion of controls here.
Notice that if register the namespaces in aspx itself, it'll work fine:
<%# Register TagPrefix="a" Namespace="WebFormsApplication1.Controls2" Assembly="WebFormsApplication1" %>
<%# Register TagPrefix="a" Namespace="WebFormsApplication1.Controls" Assembly="WebFormsApplication1" %>
So it looks like some bug in Web.config parsing.
(I'm on VS 2017, but they told me it happened since VS 2010 at least).
In cases where I needed this in the past, I had deleted the designer files and Manually declared all the controls in the code behind.
There may also be a way (but I don't recall exactly how) to tell the Designer to not generate those specific controls in the designer file. Then you manually add them in the code behind.

Visual Studio 2008 can't recognize control(in webform page) in partial class

I insert a Textbox control in webform page,but I can't find it in partial class when I use it like this.txtPaySerialNumber.Text,It looks like I had not insert that in webform page.
The old control I had inserted had no problem. I have develop web form a year, this crazy thing happened only in vs2008.(My OS is Windows 8 64).
It's not exactly clear without an example of your scenario, but a couple of things to check....
Make sure you're control is defined in the page (and properly, check the error view for bad markup declarations, etc.):
<asp:TextBox runat="server" ID="PaySerialNumber />
You'll likely noticed I summarily abandoned the awful Hungarian Notation.
Then in the code-behind, access it (omitting the double this prefix (which I'm not sure whether to take literally from your post or not):
PaySerialNumber.Text = "some text";
If that fails, try it in the markup file itself:
<script runat="server" language="CSharp">
void Page_Load(object sender, EventArgs e) {
PaySerialNumber.Text = "some text";
}
</script>
If that works, then you likely have a mismatched page declaration, so it's not pointing to the right code-behind file.
If all else fails and the page, code-behind, or whatever, still isn't seeing the thing, then try a "clean solution and then "rebuild"; perhaps even restarting VS to reload the project after a clean.
If it still isn't working, then we need more information.

C# ASP.NET Custom Control not showing up

I'm trying to construct a custom control for ASP.NET
I started by creating a Web Application in VS2010 and creating a new .ascx page. The page is called "TestBox" and it's just a single TextBox control with "This is a test" as the text.
I built the project and then included the DLL in another website in order to make sure I would be able to move controls. Based on a tutorial I found here I added the following line of code to the top of the page:
<%# Register TagPrefix="TestControl" Namespace="TestControl" Assembly="TestControl" %>
Then I added this to the page itself:
<TestControl:TestBox ID="TestBox1" runat="server" />
The code compiles and the page loads without throwing up any errors, but when it loads it's completely blank. By introducing a deliberate runtime error, I determined that the TextBox is definitely being loaded, but the control itself still isn't showing up.
Am I missing something?
Code for the TestControl:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="TestBox.ascx.cs" Inherits="TestControl.TestBox" %>
<asp:TextBox ID="TextBox1" runat="server" ontextchanged="TextBox1_TextChanged">This is a test</asp:TextBox>
I haven't touched the Designer code or the .cs code in any way.
EDIT: Figured it out. I had declared a namespace for the .CS file but not the .ASPX file itself.
The answer was that I had to add a namespace to the ASPX file itself and not just the underlying code file. I forgot to add Class="TestControl.TestBox" to the page declaration.

ASP/C# code behind can not reach control from markup

Issue:
I have a markup like this (only the important lines):
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="RTDeluxe.ascx.cs"
Inherits="MainSolution.CONTROLTEMPLATES.Kunde.RTDeluxe" %>
<ul id="linkUl" class="teaserLinksUL" runat="server"/>
The code-behind:
namespace MainSolution.CONTROLTEMPLATES.Kunde
public partial class RTDeluxe : UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
linkUl.InnerHtml = string.Empty;
}
}
I can access the ul inside the code-behind and get no compilation error. But, when I debug the code I get a NullReferenceException because linkUl is NULL.
First I thought that the namespaces are the reason. But, after several tries, I'm sure that they're correct. The FileLocation seems to be correct and the controltemplates folder of my iis has a "Kunde" folder with the corresponding ascx files in it.
I have other .ascx files with the same structure -> they're working like a charm.
Question:
Are there any other reasons than the namespace for such behaviour? Do you have any hints where I can look at?
Edit:
The RTDeluxe.ascx.designer.cs file exists, the generated linkUl looks like this:
protected global::System.Web.UI.HtmlControls.HtmlGenericControl linkUl;
Edit2:
Ok, I will try to answer all your questions. Thanks for your time and feedback!
I have restarted Visual Studio -> The Problem persists.
I also have cleaned up the solution and deployed a new one. -> The problem persists.
When I debug and check the control hierachy I can see that the label is NOT there.
When I change the ID the compiler throws an error in the code-behind (which is right). If i change the ID there two I get the same behavoiur as before.
I also restarted my IIS and the whole pc -> No changes.
I have added a Name attribute to the linkul-definition -> No changes.
When I try to use FindControl it returns NULL.
The target-framework is .NET 3.5
The linkul is NOT inside a repeater or any other controls.
Removing/changing the web.config does also not lead to a solution.
Adding EnsureChildControls before accessing the linkUl doesnt change anything.
Moving the code into Page_PreRender does also not work.
I will try out your suggestions not listed here and add them soon.
Edit3:
Here the full markup:
<%# Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%# Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="RTDeluxe.ascx.cs" Inherits="MainSolution.CONTROLTEMPLATES.Kunde.RTDeluxe" %>
<ul id="linkUl" class="teaserLinksUL" runat="server"/>
*Edit4:
Ok here some additional info I found out:
When I change something in the markup, like adding plain html text it's NOT recognized by or shown in the browser. When i do something like this:
Label label1 = new Label();
label1.Text = "hugo lives!";
Controls.Add(label1);
It is shown. It seems like in visual studio everything is fine... But "live" at the server the code-behind speaks to some weird different markup...
This might help You a bit:
On the code-behind file of the user-control at class level, add this code:
protected global::System.Web.UI.HtmlControls.HtmlGenericControl linkUl = new System.Web.UI.HtmlControls.HtmlGenericControl();
and remove the protected global::System.Web.UI.HtmlControls.HtmlGenericControl linkUl; from RTDeluxe.ascx.designer.cs file
It might be because its Object was just declared not created.
Hope this helps..
Have you tried calling EnsureChildControls before accessing the control or moving the code into OnPreRender?
Sometimes in situations such as this it may just be that Visual Studio has got into a bad state with regard to this file. I have found that deleting the files and recreating them will often resolve the issue. Make sure to copy the code somewhere so that you can paste it back into the newly created files.
Are you deploying using the visual studio publish functionality?
If so, try deleting the .ascx file on your destination server. I have had visual studio not recognize that the file has changed and then doesn't copy the new file over.
I've had a problem similar to this before in an .aspx file. It was caused by having optimizeCompilations set to true in my web.config file.
<system.web>
<compilation optimizeCompilations="true" />
</system.web>
When optimizeCompilations is set to true ASP.Net only rebuilds pages when it feels it is necessary. Sometimes it gets confused and doesn't realize you've made a change that needs a page rebuild resulting in a run-time error that the compiler doesn't catch. See here for more information about this setting http://msdn.microsoft.com/en-us/library/ms366723.aspx.
To fix the problem I had to temporarily set optimizeCompilations to false, rebuild my website, recycle my app pool, and then set it back to true again.
Hope this helps.

asp.Net <control> does not exist in current context

I am facing a problem: I have taken a dropdownList control and ID is
drpDownCountries in an ASP.NET project. The dropdownlist control is placed on page, in the code behind file of C#, while typing the control name drpDownCountries, this control ID is listed in object member list.
The code-behind code looks like this:
drpDownCountries.Attributes.Add("onBlur", "ErrorHighlight('" + drpDownCountries.ClientID + "','" + lblCountry.ClientID + "');");
But when I compile the project I am getting the following error:
Error: The name 'drpDownCountries' does not exist in the current context
I have checked this thing on different machines too, and the same error is occurring. I do not understand what the reason is or how to fix it.
Right-click on the ASPX (or ascx) file, and select Convert to web application (or something like that). That will force a refresh on the designer file.
I had this same problem and what worked for me was to make a change to the .ascx file in Design view and then save it. This finally forced Visual Studio to regenerate the designer.cs file and include my new control.
I have seen this error occur when there is a copy of the .aspx page in the project folder.
Example:
Error occurs in Test.aspx.
There is a Test-copy.aspx file in the project folder.
Delete, rename with a different extension, or move Test-copy.aspx to a different folder.
Error is resolved.
It's possible there is an error in your aspx/aspx file that is causing the designer file not to be updated correctly. You could confirm this by adding something new (eg. "") and see if you can access that. If not, something is probably broken in the markup that you'll need to fix.
So first check that your ascx document is defined like so
ExampleClass.ascx
<%# Control Language="C#" AutoEventWireup="true" CodeFile="ExampleClass.ascx.cs" Inherits="ExampleClass" %>
ExampleClass.ascx.cs
public partial class ExampleClass : System.Web.UI.UserControl
{
protected void Page_Load(object sender, System.EventArgs e)
{
}
}
In aspx this type of error often occurs when you miss runat="server"
Do not let Intellisense fool you. Sometimes (usually after fixing problems with duplicate class names), you simply need to rebuild the project and the reported errors go away. Reopening the file after the build might be necessary.
You should put some code to get help..
Anyway, the problem could be that drpDownCountries is contained within a Panel control.
The Panel control is a Container control, in that it can hold lots of
controls.
In order to access the controls within that Panel control,
you first need to "help" ASP.Net to find it.
The typical way of doing this is to use the FindControl method look here.
Code sample:
DropDownList myDrop = (DropDownList)this.Panel1.FindControl("drpDownCountries");
if(myDrop != null)
{
..somecode..
}
Recreate the project. Just create a new project and add the elements one by one and hope it won't happen again. If it does, well that's part of the Microsoft experience: recreate another project and so on, until you decide to quit your job and join open-source.
CORRECTION
I'm going to redo the project that I have been working on since the last 3 days using ASP .NET MVC. I should be using an open-source tech for sure, but too bad it's not my decision for this project to not use .NET.
If this is happening after copy/move pages to new location, or project, you may simply check if PageName.ascx.designer.cs is included in project.
There is a bug in visual studio (or maybe reshrper): It includes PageName.ascx and PageName.ascx.cs, but not PageName.ascx.designer.cs, which must be included manually.
The only thing that worked for me was to add a temp controller in the aspx file and saving it.
That generated the designer again, and my controllers are now recognized!
You can then remove the temp controller and save; it won't ruin anything.

Categories

Resources