Rendering WebControl with Empty Attribute - c#

Is it possible to build a control that derives from System.Web.UI.WebControls.WebControl that allows 'empty' attributes?
I.e. I need to output <div helloworld></div>
Ive tried overriding RenderEndTag() and this.Attributes.Add("helloworld",null) and neither work correctly.

No. The syntax used for control parsing in ASP.NET web forms requires that attributes must have a value.
The best you could do is to use inner content:
<asp:Label runat="server" id="fooLabel" Text="Hello, world!"/>
is the same as
<asp:Label runat="server" id="fooLabel">Hello, world!</asp:Label>

Looked a bit deeper, the following code works;
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
writer.AddAttribute("helloworld", null);
}
Reflecting System.Web.UI.HtmlTextWriter.RenderBegin() midway down where attributes are written shows the line:
...
this.writer.Write(' ');
this.writer.Write(renderAttribute.name);
if (renderAttribute.value != null)
{
this.writer.Write("=\"");
...
Which shows why the above works, and this.Attributes.Add doesn't (I believe a filter is run to exclude any null attribute values).

Related

How to get html control by ID that has hyphens?

I have a front end written in html that I am converting to asp, and many of the controls have names with "-" in them. This is causing crazy headaches, as there is no time to rename everything, and the ctrl-f and replace somehow breaks my css. Is there any way to access these controls in the code behind while they have the dashes? I have tried the code below.
//Can find when there is no dash in it, but that breaks the css after find/replace of full solution
HtmlGenericControl body = (HtmlGenericControl)this.Page.FindControl("page-list");
body.Attributes.Add("class", GlobalVariables.webAppSkin);
//I have also tried this, but logout stays null
WebControl logout = (WebControl)Page.FindControl("logout-link");
This is the html control:
<body id="page-list">
Sorry, that's not gonna happen.
You cannot have an element with an id containing "-", and still be a runat="server" ASP.NET control.
Microsoft's docs about the control's IDs states:
http://msdn.microsoft.com/en-us/library/system.web.ui.control.id.aspx
Only combinations of alphanumeric characters and the underscore character ( _ ) are valid values for this property. Including spaces or other invalid characters will cause an ASP.NET page parser error.
If you tried adding runat="server" to the body tag you showed: <body id="page-list">, it would give you the following line in aspx.designer.cs:
protected global::System.Web.UI.HtmlControls.HtmlGenericControl page-list;
Which is obviously throwing an exception on C# syntax.
<body id="page-list"> is not a HTML Control (i.e. an instance of (a subclass of) System.Web.UI.Control because it doesn't have the runat="server" attribute. If you were to add runat="server" then you would get a JIT compile-time error message informing you that "page-list" is not a valid identifier.
ASP.NET Web Forms 4.0 added the ClientIDMode attribute, however it doesn't allow you to set a completely custom ID attribute value. There's no easy solution for this without using <asp:Literal> or implementing your own control (or my preferred option: switching to ASP.NET MVC).
You can access controls in code behind with their ID if you write runat="server". Here is the example for your case
<body runat="server" id="testID">
In code behind you can access it like this:
body.Attributes.Add("class", value);

How do I access sub-control's HtmlControl.Style in user control?

I have a user control that contains the following text (among other things) in the .ascx file:
<div id="divLine" runat="server">
<-- Stuff -->
</div>
In the C# code, I have this property:
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public CssStyleCollection LeftStyle
{
get { return divLeft.Style; }
}
This is pretty much copied from System.Web.UI.HtmlControls.HtmlControl.cs. However, when trying to use my custom control in .aspx pages, I can't seem to access <uwc:UserControl LeftStyle="stuff"> like I could access it directly in <div style="stuff">. Is there any way to?
No answer, so I took a different approach. divLine only contained an asp.net Label, which I exposed as a public property of the control. Apparently you can do things like <asp:Label runat="server" style="stuff"/>. Intellisense will not indicate that style is a valid attribute, but it can still be used. Just like other asp.net controls, attributes the IDE doesn't recognize will still be written to HTML. Heck, once you get style=" written, you'll even get the typical drop-down guide for it.

Set a property of a custom user control in the code behind

I found this question that shows properties on a custom user control (ascx) can be assigned inline as an HTML attribute: Custom attribute in UserControl (*.ascx)?
This works great but what about if I register a custom user control on my page and want to set/get attributes from that control in my code behind?
ASPX:
<%-- I can assign ActivePage inline and this works fine --%>
<wd:NavBar ID="MyNavBar" runat="server" ActivePage="navbarItem1" />
ASPX.CS:
// I need to change the ActivePage
if (what == "internal")
{
RunInternalComparison();
MyNavBar.ActivePage = "navbarItem1";
}
else if (what == "external")
{
RunExternalComparison();
MyNavBar.ActivePage = "navbarItem2";
}
That's what I want to do but it doesn't work. Is this possible?
Do'h! This actually works. I guess Visual Studio wasn't auto generating controls. Simply adding protected NavBar MyNavBar; to the top of my Page solved the problem. I hope someone else finds this useful.

Validator controls must always have Display="Dynamic"

i've been working on this for some time now but I can't seem to be able to find the answer... Google doesn't really help me today!
I'm working on an C# website that uses a lot of forms with a lot of validation on it. Big forms which have to be typed by hand, (no problems there though).
The problem that I have is that I always want my ValidationControls to have the Display Property set to dynamic.
I have found a work around but I'm not convinced that this is the best solution.
Currently I have a BaseValidatorControlAdapter that sets the validators display type to "Dynamic" like this:
public class BaseValidatorControlAdapter : ControlAdapter
{
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
System.Web.UI.WebControls.BaseValidator _control = (System.Web.UI.WebControls.BaseValidator)this.Control;
_control.Display = System.Web.UI.WebControls.ValidatorDisplay.Dynamic;
base.Render(writer);
}
}
This is then triggerd by adding an App_Browser which looks like this
<browsers>
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.WebControls.BaseValidator"
adapterType="BaseValidatorControlAdapter" />
</controlAdapters>
</browser>
</browsers>
My question for you is. Is it possible for me to set the default value of Display for any validator control. Because my current solution just overrides what there is right now and there is no way of changing that. Therefor when the situation arrises that I do need something else then dynamic in the display option there is no solution for it.
I'm almost convinced that there is a better solution to this.
Any advice is appreciated!
Edit august 2nd 2012:
I finally settled with the solution to override the default asp.net controls and add the following constructor to them
public controlname ()
: base ()
{
this.Display = "Dynamic";
}
I added all these controls to a namespace and now I can do
<validator:RequiredField ID="RqrdFld_x" runat="server" Display="Static" />
Essentially overriding the default value in my control definition and overriding the default control Display value of Dynamic in the constructor.
This link should be helpful in solving your problem.
You can use a skin file to set defaults for web controls accross a .NET site.
I have added a folder called DefaultTheme to my App_Theme folder and added a file to it called Skin.skin, with the following contents:
<asp:RequiredFieldValidator runat="server" Display="Dynamic" />
<asp:CompareValidator runat="server" Display="Dynamic" />
<asp:RegularExpressionValidator runat="server" Display="Dynamic" />
..allowing me to have a default setting for a number of different validators (or other controls) across my website.
What you can do then use such code in Page_Init event:
foreach(Control control in Page.Controls){
if(control is System.Web.UI.WebControls.BaseValidator)
{
control.Display = "Static";
}
}
It will find all the controls and set the Display property accordingly.

Inline code not being interpreted correctly when in server-side attribute

Take the following code:
<asp:TextBox ID="txtFirstName" runat="server" title='<%=Resources.Constants.EmptyFirstName%>' /><em>*</em>
This actually generates a title attribute of <%=Resources.Constants.EmptyFirstName%> rather than executing the code (hence returning the correct value).
Is there any reason for this? Is there a fix?
Why don't you simply set the attribute value in the code behind file?
txtFirstName.Attributes.Add("title",Resources.Constants.EmptyFirstNam);
Server side controls cannot use interpreted tags '<%= %>'. It is easier to just set the value in the code behind, but if you really want the logic in the aspx, you can use data binding expressions:
On your aspx, change your tag to a databinding tag:
<asp:TextBox ID="txtFirstName" runat="server" title='<%#=EmptyName()%>' /><em>*</em>
Add this function in your code behind:
public string EmptyName() {
return Resources.Constants.EmptyFirstName
}
This is cumbersome since you would still need to call txtFirstName.DataBind()
Why don't you set the value in OnInit in CodeBehind-file?
If you are determined to do this in the aspx file as opposed to the code behind, check out this article on Expression Builders: https://web.archive.org/web/20210304125044/https://www.4guysfromrolla.com/articles/022509-1.aspx

Categories