当前位置:编程学习 > C#/ASP.NET >>

Globalized Property Grid (二)

答案:There are two entries for each property, name and description.
Now that we have different sets of resources and globalized code that is able to extract strings to be displayed depending on the current language. Our code should be updated to allow switching between supported languages.

Switching of current language

The only thing left is to make the two languages selectable. First we construct an array of supported languages in the constructor of the main form. We use the ISO 639-1 standard format for identifying languages as used by .NET: en for english, and de for german should be enough for this sample. Also, an instance of Person is created here.
        public Form1()        {            //            // Required for Windows Form Designer support            //            InitializeComponent();            supportedLanguages = new string[2];            supportedLanguages[0] = "en";            supportedLanguages[1] = "de";                        // Instantiate test class and set some data            person = new Person();            person.FirstName = "Max";            person.LastName = "Headroom";            person.Age = 42;                    }
Second, we add a combobox named cbLang to the main form. This combo box is filled with the displayable language names. The displayable language names are obtained by using a CultureInfo object. Moreover the Person object is assigned to the property grid. We use the form load event handler for this.
        private void Form1_Load(object sender, System.EventArgs e)        {            // Setup combo box with languages available            cbLang.Items.Insert(0,(new CultureInfo(supportedLanguages[0])).DisplayName);            cbLang.Items.Insert(1,(new CultureInfo(supportedLanguages[1])).DisplayName);            // Preselect the first one            cbLang.SelectedIndex = 0;            // Assign person to property grid            PropertyGrid1.SelectedObject = person;        }
Last but not least, we define an event handler to be notified when the selected index changes in the combo box because we want to change the current language. We inform the current thread about the new current language by setting its static property CurrentUIThread to a new instance of CultureInfo initialized with the ISO 639-1 name. After setting the new language a refresh of the property grid is necessary.
        private void cbLang_SelectedIndexChanged(object sender, System.EventArgs e)        {            // get the language selected from combo box            int lang = cbLang.SelectedIndex;            if( lang == -1 )                return;            // Set selected language as the current one            Thread.CurrentThread.CurrentUICulture = new CultureInfo(supportedLanguages[lang]);            // Refresh displayed properties                        PropertyGrid1.Refresh();        }
That is a basic version that demonstrates how to display custom property names and descriptions. In the sample code there is one enhancement provided.

Enhancement


The default selection of the resource string is by the class name as string table name and the property name as the string definition. This can be superposed by using a .NET attribute.
The attribute GlobalizedPropertyAttribute is defined in Attributes.cs and can be applied as follows.
        [GlobalizedProperty("Surname",Description="ADescription", Table="GlobalizedPropertyGrid.MyStringTable")]        public string LastName        {            get { return lastName; }            set { lastName = value; }        }
The example defines the display name for the property name LastName can be found in stringtable GlobalizedPropertyGrid.MyStringTable and the string is identified by Surname, the optional description text is identified by ADescription.

To get this enhancement working an addition has to be made to the DisplayName and Description properties of the descriptor class GlobalizedPropertyDescriptor:
public override string DisplayName
{
get
{

// First lookup the property if GlobalizedPropertyAttribute instances are available.
// If yes, then try to get resource table name and display name id from that attribute.
string tableName = "";
string displayName = "";
foreach( Attribute oAttrib in this.basePropertyDescriptor.Attributes )
{
if( oAttrib.GetType().Equals(typeof(GlobalizedPropertyAttribute)) )
{
displayName = ((GlobalizedPropertyAttribute)oAttrib).Name;
tableName = ((GlobalizedPropertyAttribute)oAttrib).Table;
}
}

// If no resource table specified by attribute, then build it itself by using namespace and class name.
if( tableName.Length == 0 )
tableName = basePropertyDescriptor.ComponentType.Namespace + "." + basePropertyDescriptor.ComponentType.Name;

// If no display name id is specified by attribute, then construct it by using default display name (usually the property name)
if( displayName.Length == 0 )
displayName = this.basePropertyDescriptor.DisplayName;

// Now use table name and display name id to access the resources.  
ResourceManager rm = new ResourceManager(tableName,basePropertyDescriptor.ComponentType.Assembly);

// Get the string from the resources.
// If this fails, then use default display name (usually the property name)
string s = rm.GetString(displayName);

上一个:获得临时文件的两种途径
下一个:C#中的常用例程

CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,