Thursday, September 25, 2008

Localizing column header text of datagridview using XML file

When I faced a problem involving Grid view control localization, I had come out with the code displayed here which solved the issues properly. I will like to present it here for fellow programmers. As far as the code is concerned, I can guarantee that this works.

Situation : When I was working for a MNC client project, it involves localization for all forms. For example, in a windows form named 'Employee', contains a datagridview named 'grdEmployee' with columns 'Employee ID', 'Employee Name', 'Company', 'Phone' and 'Email'.
My problem was with the Current UICulture. I need to change my current culture to 'ja'(Japanese). When I switch to Japanese culture display column header text of the grid view to the corresponding Japanese characters of the English headers.


I am using an XML file named 'GridLayout.xml' in the application base directory. Content of the XML file is shown below:

GridLayout.xml

< ?xml version="1.0" encoding="utf-8"?>
< datagridview>
< grid name="grdEmployee">
< columns language="en">
< headertext0>Employee ID< /headertext0>
< headertext1>Employee Name< /headertext1>
< headertext2>Company< /headertext2>
< headertext3>Phone< /headertext3>
< headertext4>Email< /headertext4>
< /columns>
< columns language="ja">
< headertext0>社員ID< /headertext0>
< headertext1>社員名< /headertext1>
< headertext2>会社< /headertext2>
< headertext3>電話番号< /headertext3>
< headertext4>メールアドレス< /headertext4>
< /columns>
< /grid>
< /datagridview>

The code I have wriiten in code window of the form 'Employee.cs' is as :

Employee.cs

// Import section
using System;
using System.Collections.Generic;
using System.ComponentModel;using System.Data;
using System.Drawing;using System.Text;
using System.Windows.Forms;
using System.Globalization;
using System.Threading;
using System.Xml;

// Private variable used
private string culture;

// constructor
public Employee()
{
// Getting the current culture intended to be used from the App.Config file
culture = Service.GetAppSetting("Language", "ja");
Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
InitializeComponent();
}

// Form load event
private void Employee_Load(object sender, EventArgs e)
{
// Calling the method used to localize the datagridview
LocalizeGridHeader();
}

// Method used to localize datagridview Column Headers
private void LocalizeGridHeader()
{
// calling method wriiten in class 'Service' to get XML node defined for 'grdEmployee'
XmlNode xmlNode = Service.GetXmlGridLayout("grdEmployee");
if (xmlNode == null) return;
foreach (DataGridViewColumn dc in grdEmployee.Columns)
{
dc.HeaderText = xmlNode.ChildNodes.Item(dc.Index).InnerText; // xmlNode["HeaderText0"].InnerText;
}
}

Also I have used a class named 'Service' to write the common method used in my application.The code in the class 'Service.cs' is as :

Service.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.Xml;
using System.IO;

// Method to get configuration values from the application configuration file 'App.config'
public static string GetAppSetting(string key, string defaultValue)
{
string AppSetValue = defaultValue;
if (ConfigurationManager.AppSettings[key] != null)
{
try
{
AppSetValue = ConfigurationManager.AppSettings[key];
}
catch
{
}
}
return AppSetValue;
}

// To get an XML node list from the 'GridLayout.xml' for the grid name passed in base directory
public static XmlNode GetXmlGridLayout(string gridName)
{
string language = Service.GetAppSetting("Language", "ja");
string filePath = AppDomain.CurrentDomain.BaseDirectory + "
\\GridLayout.xml";
XmlDocument xmlDoc = new XmlDocument();
XmlReader xr = XmlReader.Create(new StreamReader(filePath, Encoding.Default));
xmlDoc.Load(xr);
XmlNodeList nodeList;
nodeList = xmlDoc.SelectNodes("/DataGridView/Grid[@name='"+ gridName + "']/Columns
[@language='" + language + "']");
return nodeList.Item(0);
}

In this solution , a part of the Configuration file 'App.config' looks like:

App.config

< ?xml version="1.0" encoding="utf-8" ?>
< configuration>>
< system.windows.forms jitdebugging="true">
< appSettings>
< add key="Language" value="ja">
< !--< add key="Language" value="en">-->
< /appSettings>
< /configuration>

3 comments:

Anonymous said...

There was no need for that. You could just write appropriate translations in the column headers for each language and translate them in runtime with something like this:

foreach (DataGridViewColumn column in datagrid.Columns) pComponentResourceManager.ApplyResources(column, column.Name);

VS at least saves the column headers in localized resx files.

Dontcryme said...

Thanks For Sharing Your Idea. :-)

Anonymous said...

GridView Column Localization