Prevent Visual Studio from adding child controls - asp.net

I have a bit of a strange issue here. I created a custom control as such:
public class Textbox : System.Web.WebControls.Placeholder
{
if( [certain criteria are met])
this.Controls.Add(new System.Web.WebControls.Textbox());
}
When working in Visual Studio's designer mode, anytime I add one of my textboxes to the page:
<myControls:Textbox id="txtTest" runat="server" />
Visual studio has a habit of changing my markup to the following:
<myControls:Textbox id="txtTest" runat="server" >
<asp:Textbox runat="server" />
</myControls:Textbox>
This changes the final output markup so that two textboxes appear. Is there a way to prevent visual studio from doing this?
EDIT:
As per request, here is the page markup
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Test.aspx.cs" Inherits="TestApp.Test" %>
<%# Register Assembly="MyControls.WebControls" Namespace="MyControls.WebControls" TagPrefix="myControls" %>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<table>
<tr>
<td>
<asp:Label ID="lblTest" runat="server">Test Label:</asp:Label>
<myControls:TextBox ID="txtTest" runat="server" Width="80px"></myControls:TextBox>
</td>
</tr>
</table>
</asp:Content>

I think that's happening because your class inherits from the PlaceHolder control, which implements the TemplateControl class. I don't know if there was a reason for this, but it seems like it would be more approriate if you inherited from the TextBox control instead.
EDIT
Since you're using logic to render one of several controls, I would inherit from the WebControl class instead. This will allow you render basically anything you want. Although I must admit, what you're trying to do is probably going to require a substantial amount of work.

If I understand the issue correctly, you are having problems at design time and not runtime.
If this is the case, you should wrap your control add code with a test that ensures it is only executed when you are not in design mode. For example:
if ((!this.InDesignMode) && ( [certain criteria are met]))
this.Controls.Add(new System.Web.WebControls.Textbox());

Related

cannot access controls in asp.net application

I am working on an ASP.NET VB.NET Web Application. I inherited a bunch of forms from another application we have in house. I'm running into a very strange problem when working on the Login page.
This is an abbreviated version of my code:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="Server">
<table>
<tr>
<td>
<span id="Span1" runat="Server" style="Color: Red"></span>
</td>
</tr>
<tr>
<td>
<asp:Login ID="Login1" runat="server">
<LayoutTemplate>
<table>
<tr>
<td>
<span id="Span1" runat="Server" style="Color: Red"></span>
</td>
</tr>
</table>
</LayoutTemplate>
</asp:login>
</td>
</tr>
</table>
</asp:Content>
I have a <span id="span1"> that is located inside my web form, within the Content part of the page. I can easily access this in my CodeBehind, and do whatever I want to do with it. However, if i move that span and put it inside the <asp:login> part of the page, it doesn't seem to recognize it, it won't let me access it in code behind, it gives me a squiggly blue line and says
span1 is not declared. It may inaccessible due to protection level
This bit is from the top of the webform in designer
<%# Page Language="VB" AutoEventWireup="false" CodeFile="Login.aspx.vb" Inherits="_Default" MasterPageFile="~/Site.master" %>
This bit is from the Login.aspx.vb page
Partial Class _Default
Just to say it again, id="span1" works perfectly fine where it is shown in the code above, but when I move it inside the I cannot reference it anymore. Since I'm talking about this issue, for that matter I cannot add any new controls inside because I am not able to reference any other controls in vb.net. (this form was pretty much copied from another project, everything works properly I'm just not sure why I'm having this strange issue)
I noticed that a lot of people have similar issues, but in my case I'm working with <asp:login> and I'm really not sure how it's affecting my controls.
EDIT: <span id="Span1" runat="Server" style="Color: Red"></span>
You need to use FindControl on the Login1 Control
HtmlGenericControl hgc = Login1.FindControl("Span1") as HtmlGenericControl;
hgc.InnerText = "Span Found";
VB
Dim hgc As HtmlGenericControl = CType(Login1.FindControl("Span1"),HtmlGenericControl)
hgc.InnerText = "Span Found"
As per my comments, and as requested by the OP...
You're hitting a problem with the naming container.
When the <span runat="server"> is outside of the <asp:Login><LayoutTemplate> it exists as an object within the page, which you can reference directly.
As soon as it's moved within that <LayoutTemplate> it becomes a child of the <asp:Login> control instead.
So to access the control, you can use the following...
CType(Logon1.FindControl("span1"), HtmlGenericControl).InnerHtml = "hello"
The FindControl will bring back an object, but it needs to be "boxed" into the correct type before you can access the InnerHtml property
to access a control on server side, you must include the "runat='server'" attribute on a tag. That's what tells .NET that any given control is supposed to be worked with on the server side as well as the front-end.
Do note that it will change the ID produced in the rendered HTML
<span id="span1" runat="server"></span>

DX DateEdit controls break inside of an ACT Accordion control

I've got several DevExpress DateEdit controls on my page organized into an AjaxControlToolkit Accordion along with other fields relevant to my data.
The DateEdit controls worked quite fine until I put them into the Accordion so I'm assuming the problem is some conflict between DevExpress and AjaxControlToolkit though I have no other alternative unless there's a DX accordion type control that does the same as the one from the Control Toolkit...
The error I'm getting in my browser when I try to use a date editor is
ASPx is not defined
No other details that I could find but DateEdit fields placed outside of the Accordion work perfectly.
Note that removing the accordion is not a viable solution for this project without a possible alternative being presented.
Here's my code:
<%# Register TagPrefix="ajax" Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" %>
<%# Register Assembly="DevExpress.Web.v15.2, Version=15.2.4.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" Namespace="DevExpress.Web" TagPrefix="dx" %>
<asp:Content ID="Content1" ContentPlaceHolderID="cphContent" runat="server">
<asp:UpdatePanel runat="server" ID="upAlerts">
<ContentTemplate>
<ajax:Accordion runat="server" ID="Accordion1" EnableViewState="true" CssClass="panel panel-info"
HeaderCssClass="panel-heading" ContentCssClass="panel-body">
<Panes>
<ajax:AccordionPane runat="server" ID="apAlert">
<Header>
<h3>Alert Details</h3>
</Header>
<Content>
<div class="form-group">
<label for="dtDate">Date</label>
<dx:ASPxDateEdit ID="dtDate" runat="server" DisplayFormatString="yyyy/MM/dd" CssClass="form-control"></dx:ASPxDateEdit>
</div>
</Content>
</ajax:AccordionPane>
</Panes>
</ajax:Accordion>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
​I would normally suspect the problem to actually exist with the ViewState since I know these controls (ACT ones in particular) can mess with the ViewState quite a lot, but the Accordion isn't currently disabling the ViewState so I'm prepared to rule that out as a possibility at this point.
That said, I'm all out of ideas.
I even tried to rearrange the order in which the assemblies are registered on the page so that DevExpress is being registered after Ajax in an attempt to ensure that Ajax wasn't overriding anything that DevExpress needed.
As a last resort I tried switching the DevExpress date editors to Ajax calendar extenders but for some weird reason they don't render correctly either (no dates are visible on the calendar pop out).
How can I get these DateEdit controls working?

ASP.NET Controls are not coming in Code-behind IntelliSense

I am having an aspx page where I have added one asp.net text box control with ID and RUNAT attribute. But in Code-behind I am not seeing this control's name in the intellisense.
My page directive in aspx is as follows
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="MyProject_UI._Default" %>
I am using VS 2008. Any idea how to get rid of this?
Try using CodeFile instead of CodeBehind. The latter is a hold-over from .NET 1.1.
Also, make sure the namespaces match up between the markup and the code. Do a test compile to be sure.
I have seen this on occasion when I edit a page. When it happens to me, I close the files and open them again and it seems to fix itself.
This will happen if you are trying to include your control in LayoutTemplate. For example if you are using an asp label in a login control you have converted to a LayoutTemplate.
<asp:Login ID="userLogin" runat="server">
<LayoutTemplate>
<!--Username and password controls-->
<asp:Button ID="btnLogin" CommandName="Login" runat="server" Text="Login" />
<asp:Label ID="lblAlert" runat="server"></asp:Label>
</LayoutTemplate>
So your lblAlert will not show up on the code behind take it out of the layouttemplate or use a loop to find the control within the layout object.
var mylabel = (Label)userLogin.FindControl("lblAlert");

Conversion from Classic ASP to ASP.NET

I have to convert some code from classic ASP to ASP.NET
1) How can I best handle syntax as below, where it seems to fail because the code is inside a tag, and also perhaps because the condition is split over several tags.
2) Any tools or guidelines that are good on this kind of code?
3) Classic ADO.
<li><a<% if "" = myFolder then %> class="selected"<% end if %> href="http://<%= SERVER_NAME %>/"><%= getLocale("Home") %></a></li>
<% SQL = "SP_TOPNAV '" & lang & "'"
Set maNav = conn.execute(SQL)
do while not maNav.EOF %>
<li><a<% if maNav(0) = myFolder then %> class="selected"<% end if %> href="http://<%= SERVER_NAME %>/<%= maNav(0) %>"><%= maNav(1) %></a></li>
<% maNav.MoveNext
loop
Set maNav = Nothing %>
</ul>
ASP.net handles code split between several <%%> tags just fine. The problem lies elsewhere. Please edit your question to include the error message.
If your using .net 2.0 look into a asp:repeater that can bind to a datasource, if your using .net 3.5 look into a asp:listview. Those controls give you the ability to iterate through data and generate markup which is essentially what your doing.
You can always use ASP.NET's data controls such as Repeater, GridView, DataList to display collections of item. And you can customize their looks by modifying the ItemTemplate. You can also include the rendering conditional inside ItemTemplate too.
For example:
<asp:Repeater id="Repeater1" runat="server">
<HeaderTemplate>
<table border="1">
</HeaderTemplate>
<ItemTemplate>
<tr>
<td> <%# Container.DataItem %> </td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
Taken from: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.repeater.itemtemplate.aspx
You can always insert conditional logic inside <%# ... %> text. Or if the logic are complicated, you can code them inside the code behind file and call them from here.
Search for "ASP.NET If inside ItemTemplate" or "ASP.NET Condition in ItemTemplate" for more info.

ASP.net Inline Expression Issue

I can't seem to figure out why this does not work below. I need to bind the text box to a value from an inline expression. Seems like a simple thing right? But neither of these work. Any ideas? Thanks in advance.
<asp:textbox id="tbName" runat="server" Text='<%# Eval("test") %>' />
<asp:textbox id="tbName" runat="server" Text='<%= "test" %>' />
Edit:
I should mention that this page has no code behind and only the following directives at the top.
<%# Import Namespace="System" %>
<%# Import Namespace="System.Web" %>
<%# Page Language="C#" %>
Edit:
The only workable solution that I could come up with short of adding a code behind is adding an inline server script, like this one. I wish I knew why the inline expressions won't work unless you're in a data binding context.
<script language="C#" runat="server">
private void Page_Load(object sender, System.EventArgs e)
{
tbName.Text = "test";
}
</script>
In the Page_Load of you will have to make a call to Page.DataBind() for
<asp:textbox id="tbName" runat="server" Text='<%# Eval("test") %>' />
to work.
<%= %> is a shortened response.Write() and is never valid as an attribute, for any server tag.
<%# %> can be used, only if the conatainer is databound (the page in your case).
<%$ %> can be used to access data in resources files.
EDIT: You can also take a look at How to 'bind' Text property of a label in markup which is a smimilar question.
As stated, <%= %> is illegal anywhere within a server control declaration, except where inner markup is being parsed as content (eg <ItemTemplate> within a Repeater).
<%# %> is valid as an expression for control properties, as these expressions will be evaluated when DataBind() is called on the control.
Your use of Eval() looks a little suspect though. Per the example, Eval() will use the current Page object as the binding context, which means that the value of the public property named "test" will be bound to when DataBind() is called. Unless you actually have this property defined on the Page class, the expression will never evaluate to anything.
Eval() is mainly intended for use in expressions within controls such as Repeater, GridView, ListView, etc, where there is a list of data items being bound using templates, and you need a method to be able to access the properties of the current data item.
For all other controls, just use normal code expressions inside a data-binding expression - it's much faster, and more intuitive than Eval(), which relies on runtime reflection.
If you want a more clever alternative using <%$ %> syntax that avoids data-binding altogether, go here:
http://weblogs.asp.net/infinitiesloop/archive/2006/08/09/The-CodeExpressionBuilder.aspx
Use <asp:textbox id="tbName" runat="server" Text='<%# Eval("test") %>' />
and set tbName.DataBind(); in page load event.
For those who are searching for more info about inline expressions, refer to the following links.
ASP.net have the following inline expressions
Embedded code blocks <% ... %>
Displaying expression <%= ... %>
Directive expression <%# ... %>
Data-binding expression <%# ... %>
Expression builder <%$ ... %>
Server-side comments block <%-- ... --%>
You might need the namespace for the textbox control
<%# Import "System.Web.UI.WebControls" %>
Try adding runat="server" to the server elements.
Otherwise, this element will not be processed at server.
EDIT: Actually, "its correct" that this doesn't work; code <%=...%> cannot be evaluated in a server tag, only expressions like for instance <%$ Resources: h1 %>
<asp:textbox id="tbName" runat="server"><%="test"%></asp:textbox>

Resources