Thursday 10 December 2009

Adding an ASP.Net User Control dynamically in code behind

I was having problems with creating and adding instances of a user control to a page from the code behind eg

WebUserControl wuc = new WebUserControl();
wuc.ContentText = "Add this text to my control's custom ContextText property";
PlaceHolder1.Controls.Add(wuc);


I had the control registered on the page:

<%@ Register TagPrefix="jon" Src="~/WebUserControl.ascx" TagName="WebUserControl" %>


My user control just had to put the ContextText in a Label...


public partial class WebUserControl : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = this.ContentText;
}


public string ContentText { get; set; }
}


This didn't work and failed with a null reference exception "Object reference not set to an instance of an object" on my Label control.

The solution is in the way the user control is created. If you change the code above to...

WebUserControl wuc = (WebUserControl)LoadControl("~/WebUserControl.ascx");
wuc.ContentText = "This one is added dynamically";
PlaceHolder1.Controls.Add(wuc);

...suddenly it all works fine.

I don't understand this. I expect it's to do with the page life-cycle and the control not being created properly with the first version of the code.

Monday 29 June 2009

How to do ASP.NET Localization manually

In the "<%@ Page" declaration at the top of the aspx page add UICulture="auto" and Culture="auto".

Add a "meta:resourcekey" attribute to any element that needs localizing

eg...
<asp:label id="MyLabel" runat="server" text="Default Label Text" meta:resourcekey="MyLabelResource" />

Add an App_LocalResources folder to the solution. There seems to be some disagreement over whether and when to use App_LocalResources or App_GlobalResources. I think local unless it's something that'll be repeated on a lot of pages.

Add a new resource file to App_LocalResources folder named like "nameofmypage.aspx.resx" - this is the default language file.

Entries are then things like MyLabelResource.Text etc...

Other language resource files are created with names like "nameofmypage.aspx.fr.resx" for French or if specific to a particular region of a language "nameofmypage.aspx.en-US.resx" for US English and "nameofmypage.aspx.en-GB.resx" for Proper English etc.

That's all for aspx files. To retrieve resources programatically in C# is as simple as:

Label1.Text = GetLocalResourceObject("Label1Resource.Text").ToString();

Testing in IE, go to Tools > Options > Languages and add the appropriate entry and then move it to the top and refresh.


Globals

Globals work a little bit differently. In App_GlobalResources add a resource file eg globals.resx then to retrieve value use:

Label1.Text = GetGlobalResourceObject("globals", "myGlobalResourceString").ToString();

or in the page:

<asp:label id="MyLabel" runat="server" text="<%$ Resources:globals, myGlobalResourceString %>" />

Note the two arguments where the first is the name of the resource file (globals).


From .cs files

To get a resource programatically from within a .cs code file you just need to append HttpContext to the front of the above methods

eg HttpContext.GetGlobalResourceObject("globals", "myGlobalResourceString").ToString()


To use the current culture to format a date into the current language use:
date.ToString(System.Globalization.CultureInfo.CurrentCulture)