I want to localize an application, and currently use the App_LocalResource resx files for language changes. However, I want to change the layout of the controls on an ASPX page dependant on locale. I know it is possible to set visible from the resx file.
For example; my default (en-US) could have
"firstname" : [textbox]
"surname" : [textbox]
where as de-DE I would want to swop the order
"surname" : [textbox]
"firstname" : [textbox]
The aspx pages will use the same CodeBehind.
I guess what Im looking for is something along the lines of having;
default.aspx
default.de-DE.aspx
default.aspx.cs
Where the default.de-DE.aspx contains all the same controls etc as default.aspx and even has the same directive;
<%# Page CodeFile="Default.aspx.cs" Inherits="MyNamespace.Default" %>
Then the .NET framework picks up this one rather than default.aspx layout..
I have worked for quite some time on a project that does essentially what you are looking to do; We split it by folder is the only difference, so /en-US/Default.aspx and /de-DE/Default.aspx. The pages share a common code-behind for functionality. It works pretty well, with a few gotchas:
Making sure the files are always updated together - This is necessary because of the shared code behind. If you update the code behind, all the referenced controls had better exist on the pages.
Be careful about your control references - we've run into some issues where controls were referenced from the wrong folder, resulting in some interesting (and sometimes hard to diagnose) issues.
Personally I would recommend splitting it into folders instead of using the file naming structure because it also very easily allows you to provide locale specific images and CSS . Also it allows you to override the common behavior of a page by just adding the appropriate code behind (you could do this too, but then your class names will be strange due to the periods in the file names[eg. ApplicationNS.Default_de_de as opposed to ApplicationNS.en_us.Default]).
In a similar situation I've created a custom server control with a localizable "RenderOrder" property. It also exposes Surname and FirstName as properties.
A similar scenario sometimes is required for detailed address fields too.
I would say the best way to handle this would be via CSS.
You can easily apply a different stylesheet, which can completely change the layout of your website, and thereby move all the controls around. This solution also allows you to easily do alternate renderings for mobile browsers, or printing, or any other reason and is very versatile.
As other s stated, you will obviously have other localization issuse such as translation or date/currency formats as well. But you will have to solve those via other means.
Here are some examples of the same website, with 100% the same HTML, where only the CSS has changed, rendering completely differently.
http://www.csszengarden.com/?cssfile=/212/212.css&page=0
http://www.csszengarden.com/?cssfile=/211/211.css&page=0
Assuming your simple case where you have just two controls that you want to flip :
<div>
<div class=class1>Control1</div>
<div class=class2>Control2</div>
</div>
Then based on the location, in your stylesheet use either floats, or absolute positioning (within the parent container) to reposition the two divs. 100% identical html, with two different layouts?
ASPX
<link rel="stylesheet" id="Stylesheet1" type="text/css" runat="server" />
ASPX.cs
Stylesheet1.Attributes("href") = ResolveUrl("~\styles\StyleSheet.css")
I should vote for building a control that's the way you display dates and times which is heavily dependent on localization
Resources and Localization in ASP.NET 2.0
Custom ASP.NET Server Controls and Language Localization
Good general article on localization
Related
Is there a way to reuse a piece of ASP.NET code (that tag-based code, not the code-behind) in many different pages? For example I have a <div> with some contents in it that appears in 5 different pages of my site. I'm looking for a technique through which I could save this <div> in a separate web-content file so to speak, with maybe a different extension like MyDiv.ASPC and could then do a server-side tag anywhere in a webpage like:
<asp:Import href="~/MyDiv.aspc" />
and ASP.NET would inject the entire content of this file at that point where this tag appears.
I thought of creating a user control for this, but I'm not sure if a user control always injects precisely what is written in its body, or could there sometimes be unwanted tags generated by user control itself.
Or are there existing better ways of doing this?
Edit
About Master Pages, they are far away from what I'm looking for. They are actually good for a common basic layout of your website. My idea is quite opposite of that. My pages do not have a common layout; it is just that they have one common <div>. It is more closely fulfilled by a UserControl.
For UCs, my fear is that they generate more than what is written in their body, whereas what I'm after is a simple text injection. To put it technically, what I'm looking for is basically a preprocessor step (kind of #include thing in C++) rather than a compiler step, if you see what I mean.
You need to use ASP.NET User Controls, as these are specifically created to be the solution to the problem you are describing. For more information, see MS Documentation.
From their documentation...
In addition to using Web server controls in your ASP.NET Web pages,
you can create your own custom, reusable controls using the same
techniques you use for creating ASP.NET Web pages. These controls are
called user controls.
A user control is a kind of composite control that works much like an
ASP.NET Web page—you can add existing Web server controls and markup
to a user control, and define properties and methods for the control.
You can then embed them in ASP.NET Web pages, where they act as a
unit.
An empty userControl would do just that - nothing. A user Control just adds it's contents to the page, or usercontrol hosting it. It adds nothing extra.
UserControls give you a nice easy page fragment type approach to reusing content. They work great within a project & most people use them for just that.
If you wanted to make something more reusable across projects, you could write server control. It's more involved, but much more reusable. Google should be able to find you many tutorials on how to do this.
Ran a short test. User Controls do not enter extra tags as long as you don't place any Runat="Server" tags in it, so this would indeed be a solution I guess.
You can also read output from a cache object where you would read your files.
So
<%= Static.ContentXyz %>
would mean:
public static class Static
{
public static string ContentXyz
{
get
{
string s;
if (!this.cacheDictionary.TryGetValue("ContentXyz", out s))
{
s = File.ReadAllText(Server.MapPath("ContentXyz.html"));
this.cacheDictionary("ContentXyz", s);
}
return s;
}
}
}
I would like to understand how can I use jQuery to work with asp.net and css.
When I'm writing asp.net code and for example I'm adding to a page DropDownList, I can't see it in the source when I'm opening source of a page in web browser. Instead of dropdownlist I can see select tag. When does the "magic" is done to change asp.net tag to select?
What is more I can't see my CSS classes names added to asp.net tags. There are some kind of differen CSS class names. But when I'm opening developer tools in IE, I can see CSS class names, which are same as in my definition.
And the last thing. What names of a tags sould I use in jQuery to traverse page which was developed in asp.net. Shoud I use a tags which I see in the source code of a page in a browser or can I ask jQuery about asp.net tags? What about CSS classes? Why I can't see them in a source of a page in a browser? Can use my names of a CCS classes under jQuery queries?
Please, can anybody explain me how does this three technologies work together?
When does the "magic" is done to change asp.net tag to select?
Most of "magic" you're wondering about is done by ASP.NET controls, which are designed to generate the markup that is sent to the browser.
When a request is received, the application iterates over each control, calling its Render method (inherited from the Control class), which allows each control to generate the markup they represent.
Following your example, the DropDownList control generates a <select> tag. As a ListControl, it uses the ListItem controls to create the <option> tags within.
Another would be the GridView, which generates a <table> using GridViewRow controls for <tr> and various HTML Controls, such as TableCell for <td> and <th>, to create the rest of the markup.
Shoud I use a tags which I see in the source code of a page in a browser or can I ask jQuery about asp.net tags?
No, jQuery/JavaScript have no knowledge of server-side control names, only the markup they generate. So, rather than searching for $('DropDownList'), you'd search for $('select').
What is more I can't see my CSS classes names added to asp.net tags. There are some kind of differen CSS class names.
By "CSS Names," do you mean IDs? I'm sorry to ask, but CssClass attributes shouldn't change in value from server-side to client-side, just in name -- CssClass to just class.
IDs, on the other hand, are prefixed to ensure their uniqueness throughout the page, including a prefix of the MasterPage and ContentPlaceHolder names, if they're used. For this reason, I'd steer away from trying to use IDs to apply CSS to server-side controls, using classes instead.
Now, the end of the ID should remain as the ID you gave in server-side, so you should still be able to find the element in jQuery using the Attribute Ends With Selector [name$='value']:
# ASP
<asp:DropDownList ID="AnyGivenDropDown" runat="server" />
# HTML (generated)
<select id="ctl00_PageContents_AnyGivenDropDown"></select>
# JavaScript
$('select[id$="_AnyGivenDropDown"]');
Otherwise, I'd stick to classes to find the controls you're looking for:
# ASP
<asp:DropDownList ID="AnyGivenDropDown" CssClass="anygiven" runat="server" />
# HTML (generated)
<select id="ctl00_PageContents_AnyGivenDropDown" class="anygiven"></select>
# JavaScript
$('select.anygiven');
# CSS
.anygiven { }
The "magic" happens in the render event of the asp.net page lifecycle. Asp.net server controls all render as standard html element(s). The most important difference is that you can access them and their values on the server side. WebControls also have a CssClass property that when rendered becomes the class attribute of the HTML element.
The id can be a bit tricky when working with jQuery and CSS. This is because depending on the controls hierarchy they may have a clientID such as ctl100_containerID_myControl instead of myControl. To overcome this in jQuery when you reference a control you can refrence it by its ClientID like so:
$('#<%=myControlID.ClientID%>')
This is serverside that will write the client side ID of the control after it is rendered.
ASP.NET: High-level web development framework. When you create a web form in .NET, the framework will work together with the IIS handlers and create (hopefully) valid HTML that will work with your server-side code during postbacks.
JQUERY: This will allow you to perform client-side scripting such as calculation, validation, and most notably AJAX, etc. This is basically just a wrapper for a simpler and easier-to-read version of javascript.
CSS: Takes the HTML and makes it pretty.
All three technologies work very well together if you know what you're doing.
I'm not sure if that's what you're looking for, but it sounds like you might want to invest in some beginner's literature.
I am designing an ASP.NET v3.5 custom control based on CompositeControl.
However, I do NOT want to create my child controls via code, but rather as
embedded HTML tag elements within the CompositeControl in the ASPX page, such as:
<cc:MyCompositeControl ID="MyControl">
<asp:Label>Cat</asp:Label>
<asp:Label>Cat</asp:Label>
</cc:MyCompositeControl>
At run time, MyControl.Controls contains the two labels as expected.
At design time, MyControl.Controls is empty.
I need this information at design time for various reasons.
What am I doing wrong?
You might consider taking a look at the System.Web.UI.WebControls.Panel control in the System.Web DLL using Reflector. That will help you get some idea of what properties and what attribute decorations are necessary to provide the design-time support you need.
I generally prefer to add controls dynamically, like table and generic html controls, to the ASPX page, rather than add them in the ASPX page and set the properties dynamically.
Which approach is considered "better practice"?
Also is using generic html controls dynamically a better practice than outputting formatted html strings to an asp:literal?
Keep them in the .aspx
Adding them dynamically leads to view state issues and they must be added in each post pack. I ran into this when building a user generated forms app. I Broke down and used the controls visibility property as a work around. That said if your eliminating view state and post back from your app these may not be issues for you.
https://web.archive.org/web/20211031102347/https://aspnet.4guysfromrolla.com/articles/092904-1.aspx
Since in both approaches you end up with a set of code that adds controls and assigns values to their properties then the best practice is the approach that is the most readable.
Due to complex decision logic it may be better to do it all yourself on the hand for fairly static control layout where only the properties need modifying placing the control in the ASPX would be more straight-forward.
In ASP.NET (not MVC), what is the best approach to programmatically setting styles on an unordered list used for navigation so the appropriate menu item is styled as the active item if that page is being viewed?
This would most likely be used in conjunction with a MasterPage.
The answer to your question depends a lot on how you have your list implemented {User control or not, etc}. How I would do it, is implement the list to be generated by a user control.
I'd have the UserControl tag each element with something like:
<{...} class="GeneratedMenuItem"> {...}
And I'd have the appropriate styles in the Style Sheet; of course if it was in a user control then you might be able to use Themes (but that depends on which version of ASP.net you are using.
Good question, I have played around with various methods of doing this since the bad old days of asp, and am yet to find the perfect hammer.
Generally I have used the Request.Url.AbsoluteUri (or similar) as an argument to whatever the rendering function was, and most often set a css class of "current" or similar on the appropriate node, as well as rendering child nodes as needed.
I have most often used an xml/xsl combination, which can usually be worked against most cms platforms, although I have never been that happy with the overhead of firing up an xsl transform just to output a nav list, but if you know xsl, is a very nice tool for generating html, and you can always cache the output - for little static html sites which come up occasionally, I often use this approach in a build process to render static menu markup.
Have also used the aspnet sitemap functionality a few times, which is pretty good if you use the css friendly adapters with it - the default rendering makes very ugly markup.
I found this article earlier this weeek: http://blog.devarchive.net/2008/01/auto-generate-strong-typed-navigation.html which uses t4 templates to make a strongly typed navigation class, and I will definately be investigating that further.
The way I took this approach was to create ASP.NET Hyperlink Controls for each of my navigation items in my master page.
Within the master page, I then created a public method that would assign the appropriate "selected" CSS style to the control I specify:
Public Sub SetNavigationPage(ByVal MenuName As String)
DirectCast(Me.FindControl(MenuName), HyperLink).CssClass = "MenuCurrent"
End Sub
Then in my content pages, I simply had to reference the master page accordingly.
Dim myMaster As EAF = DirectCast(Me.Master, EAF)
myMaster.SetNavigationPage("hypSearchRequest")
This gave me the flexibility to add/remove navigation items on various pages and also be able to assign multiple pages to the administrator navigation option when necessary.
It is also interesting to note that referencing the hyperlink control and setting the Visibility attribute (for hiding administrative pages) didn't work. This is due to the order in which the master and the content pages load. Instead, I created another CSS class that simply set the visibility property and used the same approach as above.