VB.NET · December 12, 2006 0

Switch the input language of the TextBox Control automatically upon receiving focus

This tutorial sparked off from my own ventures to incorporate a particular feature in a software I’m currently working on. It uses a mixture of languages (English & Thai) on a couple of screens to store user data. Certain data like First & Last Names & parts of address were to be entered in Thai – while the rest were in English. Now the current language can be easily switched by pressing Alt + Left-Shift (or whatever key combination you’ve set your system to) – but when you consider the same key-combination has to be repeated for over 20 fields on each screen, times the number of records you have to enter, then is becomes a dull and extremely tedious venture. This might lead to a lot of typographical errors too. In my case the users of my software had to enter over 4000 student records and you can imagine the amount of key-clicks spent on switching languages in every second field. I set my mind upon to make the lives of those poor guys a little easier and came up with this solution.

My thoughts were – why not let the software do the language switching instead. I mean, the fields which were supposed to be in English and Thai – were fixed, i.e. you couldn’t use these languages alternatively. So why not let the system switch to Thai upon focus on such a Thai data entry field and likewise for English ? The solution I’m providing here should suffice for anyone who might face such a situation (which I believe is very very common). This code will work for any language combination (or even more than two languages) with extremely minor modifications. Of course, you HAVE TO HAVE all these language packs installed on Windows to be able to switch back and forth between them.

First things first:

One convention I found very useful in achieving this effect, is to include part of the language name in the Name property of TextBox – this can then be used to easily determine which language to switch to in the corresponding TextBox. Following this, I named all my Thai TextBoxes ending with the word “Thai” and “Engl” for the English ones.

I’ll try and do the write-up in a step-by-step manner for ease of understanding.Let us start by firing up the VS.NET Studio & creating an empty VB.NET project with just one form. Add at least TWO textboxes to this form (feel free to add more and experiment around with them – but for demonstration’s sake, am going to use just two). In the Property Inspector enter txtNameThai as the name of the first box, and txtNameEngl for the second one. That’s it – the stage is set. Onto the actual code now.

Go to the Code View of the form and create the empty skeleton procedures for the Focus event of the first TextBox. When you first create a skeleton event handler procedure, using the dropdown boxes on top of the editor, the basic structure looks like this:

Private Sub txtNameThai_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs)_
        Handles txtNameThai.GotFocus 
End Sub 

Now, supposing we have over 20 different TextBoxes on the form – writing the language switching code for ALL of them is tedious and produces useless, redundant code. So we’ll point the event handlers for ALL the TextBoxes to this one procedure. I simply modified the code a triffle bit to handle the focus event for the second TextBox too. READ THE COMMENTS.

' Modified code to handle focus events of ALL textboxes 
' Notice how I simply added the the focus event of the second textbox after the Handles clause 
' If you have more than two textboxes, add the names of all of them here separated by commas. 
Private Sub Textboxes_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs)_  
	Handles txtNameThai.GotFocus, txtNameEngl.GotFocus 
End Sub 

Next step is to incorporate the actual code to switch languages. Since this subroutine handles the focus events of multiple TextBoxes, we’ll use the argument sender to determine which control has current focus – and also determine the language to be switched to using the same. Add this code inside the stub…

Private Sub Textboxes_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs)_
		Handles txtNameThai.GotFocus, txtNameEngl.GotFocus 

	'This iterates through all the installed languages and determines if there's a language 
	'installed on the system that contains the word THAI 
	
	If sender.name.endswith("Thai") Then 
		For Each Lng As InputLanguage In InputLanguage.InstalledInputLanguages 
			If Lng.Culture.DisplayName.ToUpper.StartsWith("THAI") Then 
				'If found switch the input language to that 
				InputLanguage.CurrentInputLanguage = Lng 
				'No more iterations needed since language has been found - so exit the for loop 
				Exit For
			End If
		Next
	Else 
		'English code follows exactly same syntax - except that THAI is replaced by ENGL 
		For Each Lng As InputLanguage In InputLanguage.InstalledInputLanguages 
			If Lng.Culture.DisplayName.ToUpper.StartsWith("ENGL") Then 
				InputLanguage.CurrentInputLanguage = Lng 
				Exit For
			End If 
		Next 
	End If 

End Sub

A little explanation: I’m using the sender.name property to bring up the name string of the currently focused control. Remember, how I emphasized on picking a name for each ending with the name of the language – notice how it comes to handy here.

If sender.name.endswith("Thai") – determines if the control’s name ends with the string “Thai”. If found so, we step into the next line, which is a For Each loop. Now we can skip this line and switch the language directly, but a better way would be to use the For..Each loop, as this implements an extra check for the installed languages on the system. This safeguards the case, where the desired language is missing from the system – and blocks the possibilities of runtime errors when the code tries to switch to a non-existent language.

Notice that for the second case, am not checking whether the name of the TextBox ends with “ENGL” – since there are only two possible cases here. If you need to switch between more than two languages, you need to implement cross-checks for the Name string and implement more than two If-else conditions to switch to an appropriate language. An ideal coding practise in such a scenario would be to use a SELECT CASE block instead of If-Then and inspect the sender.name and then act accordingly.
Another small trick than you can add to this to enhance your interface is – change the background color of the TextBox which has current focus. This allows the user to follow the field being currently edited in a much easier manner. All you’ve to do, is in this same GotFocus procedure, you add one more line after switching the language.

'Change back-color to PapayaWhip (or any color of your choice) on focus
sender.backcolor = Color.PapayaWhip

Remember, if you use this trick – you’ll also have to implement the LostFocus procedure which will reset the TextBox’s back-color to white upon loosing focus – else all your TextBoxes will end up with the focus color as you navigate through them.

'Method to turn the fields white on lostfocus
Private Sub TextFields_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtNameThai.LostFocus, txtNameEngl.LostFocus
	'Change back-color to white on lost focus
	sender.backcolor = Color.White
End Sub

As demonstrated here – this code switches the back-color to white upon loosing focus – and once again handles all your textfield in a single procedure.

Hope these two nifty tricks help you enliven your application – I for one find them very very useful – and from personal experience, these make the users happy too – as they have to use far less keys.

Download

LanguageSwitcher (Demo)  (16.3 KiB, 23,065 downloads)

Comments & Feedbacks will be much appreciated. 🙂