Silverlight 2 (beta1): International (Non-US) TextBox

by Christoph Husse

This is a guest post by Christoph Husse. This is a workaround for the issue #7 of Silverlight 2 (beta1) known issues . Thanks a lot, Chirs!
~ Michael Sync

Download ~

License : MIT-License

1. Introduction

… I was writing a simple logon screen and without any prejudges I tried to enter my E-Mail-Address with my German keyboard… Oh damn what’s this? Silverlight didn’t recognized the “@” char. After some googling I found out why. Silverlight does currently support US-keyboards only. Microsoft, how do you explain this? I mean it’s not hard to support all keyboards; instead it is hard to not support them. Windows by default automatically translates all keyboard codes depending on the user selected keyboard. So it’s simply unknown why Microsoft has dropped support for all other keyboards… Even if portability would be an (cheap) explanation, they didn’t care much about Mono till now, why should they do for Moonlight? I think portability is one thing, to exclude billions of people from using Silverlight sites is another one…

With this little story in mind I wrote a little TextBox supporting my German keyboard and the password chars. For your convenience I decided to use an abstract keyboard class, so any other keyboard may be implemented without much effort. The following shows a simple InternationalTextBox in action:


InternationalTextBox MyBox = new InternationalTextBox();

public Page()
{
InitializeComponent();

MyBox.Keyboard = new German_Keyboard();
MyBox.AcceptTabs = true;
MyBox.Width = 200;
MyBox.Height = 30;
MyBox.Margin = new Thickness(100, 150, 0, 0);
MyBox.HorizontalAlignment = HorizontalAlignment.Left;
MyBox.VerticalAlignment = VerticalAlignment.Top;

LayoutRoot.Children.Add(MyBox);

}

1.1 Support for any keyboard

The main feature is that any keyboard may be used with this component. Currently only the US- and German-Keyboard are supported. But if you look at the source code of those two classes “German_Keyboard” and “US_Keyboard” you will find that it is pretty easy to add your custom keyboard.

You may set the keyboard in the “InternationalTextBox.Keyboard” property. A value of “null” will use the default US-keyboard.

I encourage anyone who got a keyboard not already covered, to write a proper keyboard class and publish it. So we all can take the full advantage of support for any common keyboard layout.

I was really happy to discover, that “Ctrl+v/c/z/y” will work well on my “InternationalTextBox” and even for free…

1.2 Keyboard lists

To work with all of those keyboards, you may enumerate them through “TextBoxKeyboard.Keyboards”. Each of its entries will publish a “Description” that may be shown in a combo-box to the user and a “CreateInstance()”. The latter will allow you to get an object for every keyboard the user selects. You can then directly apply this object to the “InternationalTextBox.Keyboard” property without knowing which keyboard class you are really using…

1.3 Support for typing chars with “Ctrl + [Code]”

Even if windows uses “Alt + [Code]” for the same thing, “Alt” is reserved for the browser and can’t be used in this case. The following picture shows the use of “Ctrl + 9787” which renders a smiley icon…

I’m special.

You may use the “Ctrl” shortcut at any position and you may also use it to replace a text selection.

I think the exact rendering depends on the font selected for the TextBox! Different fonts may produce different symbols for the same control code.

1.4 Password chars

I decided to preset the password char to the one used by windows. You may enable or disable the password chars by setting “InternationalTextBox.IsPassword” to either true or false. Existing text will be converted to circles and circles will be converted to text depending on the current state to switch.

password.JPG

You may select a few circles with the mouse or by holding “Shift” while stepping through the chars with the arrow keys. It is supported to replace such a selection with a new char. The internal password string will be updated appropriate. Of course you may not use “Ctrl+c” for passwords and also “Ctrl+v/z/y” won’t work because they are intercepted by the textbox and would operate on circles only… But I think this is not an issue because passwords shouldn’t be in clipboard.

2 How to derive your own keyboard

Just create a class derived from “TextBoxKeyboard”.

At the beginning you should override the “Description” property and set it to the description used by windows for your keyboard…

Then you have to overload the “HandleKeyDown” method. This is the complicated part. The base class will take care over “Shift”, “Alt” and “Ctrl” states and also supports the direct character input using “Ctrl + [code]”. So your only duty is to translate the key code to a Char depending on the current keyboard state. To support special chars you may use so called key translation tables:


private KeyToChar[] Default = new KeyToChar[]
{
new KeyToChar() { Code = 220, Char='`'},
new KeyToChar() { Code = 219, Char='-'},
new KeyToChar() { Code = 221, Char='='},
new KeyToChar() { Code = 187, Char=']'},

The “Code” is just the native key code you may determine by setting a proper breakpoint and then pressing a proper key. The “Char” is the value you would expect to appear if the key is pressed. There are three tables. The “Default”-Table is active when none of “Shift”, “Ctrl” or “Alt” is pressed. The “Shifted”-Table is active when “IsShiftDown” is true. The “Alted”-Table is active when “IsCtrlDown” and “IsAtlDown” are true. This emulates the “Alt Gr”-key available on German keyboards for example.

If you use code as shown in the two built-in keyboards, you just have to fill those tables to support your keyboard.

Things will start getting weird if you have to do things like me with the German keyboard. For example if you press the “^” key, it is not written to the TextBox. Instead the keyboard “waits” for the next char. If it is a vocal, the resulting char is either one of “â, ê, û, î, ô”. All other inputs will generate “^[+char]”. But as you can see in the German keyboard class, this is also not very hard to handle…

Updated:

3. Remember user’s keyboard selection

If a user is visiting your site for the first time, he has to select a proper keyboard layout. I recommend to select the US-keyboard by default to be consistent with the current silverlight TextBox. Another option would be to “guess” the layout by interpreting the HTTP-Headers, especially the language. In general the user language will directly map to his keyboard layout. But of course, this is not always the case. I don’t know if Silverlight has any option to directly retrieve the user language. If not, then you have to implement this by using a server side script, and that’s definitely out of scope for my TextBox!

In the following I will just show how such a “remembering” of the user selection may work with Silverlight. You have to change the InternationalTextBox’ instance constructor code to the following. I have to admit that this doesn’t look so pretty…


public InternationalTextBox()
{
KeyDown += new KeyEventHandler(ExtendedTextBox_KeyDown);
KeyUp += new KeyEventHandler(ExtendedTextBox_KeyUp);
TextChanged += new TextChangedEventHandler(
ExtendedTextBox_TextChanged);
SelectionChanged += new RoutedEventHandler(
ExtendedTextBox_SelectionChanged);

try
{
IsolatedStorageFile File = IsolatedStorageFile.GetUserStoreForApplication();

IsolatedStorageFileStream Stream = File.OpenFile("InternationalTextBox.keyboard.layout", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

using (Stream)
{
BinaryReader Reader = new BinaryReader(Stream);
String Selection = Reader.ReadString();

for (int i = 0; i < TextBoxKeyboard.Keyboards.Length; i++)
{
if (TextBoxKeyboard.Keyboards[i].Description.CompareTo(Selection) == 0)
{
m_Keyboard = TextBoxKeyboard.Keyboards[i].CreateInstance();

break;
}
}
}
}
catch
{
m_Keyboard = new US_Keyboard();
}
}

And you have to change the InternationalTextBox’ Keyboard property setter to the following:


set
{
if (value == null)
value = new US_Keyboard();

// copy cap locks and so on...
value.Attach(m_Keyboard);

// register user char event...
value.OnUserChar += new UserCharEventHandler(value_OnUserChar);

m_Keyboard = value;

try
{
// keep this selection in "mind"
IsolatedStorageFile File = IsolatedStorageFile.GetUserStoreForApplication();

IsolatedStorageFileStream Stream = File.OpenFile("InternationalTextBox.keyboard.layout", FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);

using (Stream)
{
BinaryWriter Writer = new BinaryWriter(Stream);

Stream.SetLength(0);
Writer.Write((String)m_Keyboard.Description);
}
}
catch
{
}
}

I didn’t implement this directly because it’s just one of many options to realize “remembering”. The problem with this code is that every time you set the “Keyboard” property, the user’s selection will be overwritten. So you shouldn’t set this property directly, but you may use a ComboBox holding all the supported layouts. If the user explicitly changes the selection of this ComboBox you may also change the “Keyboard” property. I recommend implementing this ComboBox in a way the user is used to by Windows. So simply put a button with a keyboard icon beneath your TextBox. If the user clicks the button, a list containing all possible layouts should appear.

Another approach would be to check weather this file exists and contains a valid selection. If this is not the case you may display an exclusive screen only intended for layout setting. This allows you to force the user to select his keyboard layout before he can do anything on your site, maybe in style of the Windows Vista Account Control Screen.

65 Comments so far »

  1. nirav said

    am April 8 2008 @ 8:17 am

    This is a great tool. Thanks for this.
    Am facing a problem that whenever I press ‘@’ it is replaced by “/”. it is not appearing as original @ char in my textbox.password property.
    what should i do?

  2. Christoph Husse said

    am April 8 2008 @ 8:40 am

    >it is not appearing as original @ char in my textbox.password >property.
    >what should i do?

    In general this is not an issue of the password box. Did you try it with IsPassword = false?? If you’re still getting the same problem without using the password chars, please check if your keyboard is german or US… If you use neither of them, your keyboard is just currently not supported. If this is the case please let me know which keyboard you are using….

    If it only happens when password chars are enabled you seriously found a bug. But I don’t think so ;-)… The password and the real string are determined by the same method so there shouldn’t be any differences at all…

    regards
    chris

  3. Michael Sync said

    am April 8 2008 @ 8:41 am

    Hello Nirav,

    This textbox is developed by Christoph. not me.

    I think Chirs will reply you as soon as he can.He will provide you more information about that.

  4. nirav said

    am April 8 2008 @ 8:46 am

    I require @ in IsPassword=true mode ;
    what happend is if i type neel@231 then
    it will appear as
    textBox.Password=”neel”"/”231

  5. Christoph Husse said

    am April 8 2008 @ 8:53 am

    I just checked it with the same code as is downloadable above…
    If I type “neel@231″ I will get “neel@231″ with password enabled!

    Yes of course, that should work! So my recommendation is to tell me which keyboard you are using… Please keep in mind that if you use the TextBox with a keyboard different than set through “TextBox.Keyboard”, you will get exactly those mistakes you describe, because characters are not mapped correctly!

    So my guess is that you use a keyboard different to US or German, or you just forgot to select it with the “Keyboard” property. Please check this and call me again :-)

  6. Christoph Husse said

    am April 9 2008 @ 12:59 am

    I hope you don’t mind, michael… for public interest I post your question here…

    >Why do we need to switch the keyboard to use your textbox?

    >For example: I created and published one silverlight web site. I >want people from all over the world to use my site. So, there will >be some people who are using US-keyboard. At the same time, there >will be some people who are using Non-US keyboard. So, the textbox >should be able to work with both US keyboard and Non-US keyboard. >I have tested with US keyboard while setting German keyboard. It >doesn’t work. Why?

    Well, because Windows doesn’t know this either… How should my TextBox know it then? Remember if you install Windows, you have to select the keyboard layout to use… And if you switch your keyboard you also have to switch this layout…

    There is simply no way to do what you want when it’s not supported by OS. So my intention was, like I pointed out, to let the user select it’s layout once, and store this selection in a cookie or isolated storage or whatever…

    If someone finds a way to “guess” the keyboard from the HTTP-Headers this would be also an option. Maybe a good guess would be to select “German” keyboard if the user accepts german as language and so on… But this won’t work for all cases…

    regards
    chris

  7. Michael Sync said

    am April 9 2008 @ 1:13 am

    Thanks for your reply, Chris.. So, there is no way? then, it would be a lit bit trouble for us.

    Let’s say you write a comment in my blog.. You can write in Japanese, Chinese or German or English, right? I don’t need to have so many textboxes for all language. right? Otherwise, I will need to say like “Leave a comment in this textbox if you are using German Keyboard” or “Leave a comment in this textbox if you are using US Keyboard” or etc.

  8. Christoph Husse said

    am April 9 2008 @ 1:22 am

    Not that’s not true ;-)…

    Like I said you have to provide a button like windows does in it’s logon screen. This button may contain a keyboard icon. If you click this button you may switch the layout… The selected layout is stored in a cookie and you will never have to switch it again for the specific website. And because a cookie is user-specific, your website does automatically select the right layout for each user visiting your site for more than one time…
    Of course this would be an extension to my text-box…

    And also if you select the keyboard depending on the language evaluable by HTTP-Headers, you will get a correct preselection of layout in let’s say 90% of all cases…

    So there is no reason to worry about. And if you preselect the US-keyboard you will even get what you already have. Support for all US-users. And all non-US users may select their specific keyboard…

    Allright?

    :-)

    best regards
    chris?

  9. Michael Sync said

    am April 9 2008 @ 1:31 am

    Hi Chris,

    Okay.. sound great, buddy.. I like your idea “a button with keyboard icon”.. thanks a lot for writing great article and giving me full explanation for my question..

    I’ll gonna use your textbox as a password textbox in my small project… thanks again, man…

    Regards,
    Michael

  10. Christoph Husse said

    am April 9 2008 @ 1:36 am

    Not a problem at all…

    Maybe somebody has the time to realize this cookie idea and the guess by using HTTP-Headers… Currently I don’t have time to do this but I would do it before releasing my webservice… So if until then nobody provides such code or Microsoft still doesn’t support all keyboards, I would implement those both features as well…

    regards
    chris

  11. Dirk said

    am April 9 2008 @ 6:15 pm

    Man, I can hear the Flash developers laughing already…
    How come Silverlight doesn’t have access to the actual character that was keyed in? This way you can’t even see if the Caps Lock is pressed or not…
    Having to know which keyboard layout a user has throws us over ten years back in time.

  12. Christoph Husse said

    am April 10 2008 @ 1:44 am

    >Man, I can hear the Flash developers laughing already…

    Me too, me too :-(… I would also laugh if it wouldn’t be so sad…

    >This way you can’t even see if the Caps Lock is pressed or not…

    You can… My keyboard class has the properties “IsShiftDown”, “IsAltDown”, “IsCtrlDown”, “IsCapsLock”.

    >Having to know which keyboard layout a user has throws us over
    >ten years back in time.

    I would totally agree… I hope Microsoft’s only explanation is that silverlight is still under extensive development and of course will support all keyboards at last in silverlight 3!!!!
    Otherwise I don’t see a great future for it…

    regards christoph

  13. Dirk said

    am April 10 2008 @ 2:55 am

    >My keyboard class has the properties “IsShiftDown”, “IsAltDown”, “IsCtrlDown”, “IsCapsLock”.

    Thanks, I didn’t know about that.

    I think this might get funny after all…
    Line of Business applications? Imagine you having to explain to your boss you transferred 10.000 £ instead of $ because the user selected the wrong keyboard setting :-)

  14. Christoph Husse said

    am April 10 2008 @ 3:42 am

    >transferred 10.000 £ instead of $ because the user selected the wrong keyboard setting

    That’s pretty funny ^^…
    Even I think this way it won’t work. Only if he is the user. But it does not matter at all ;-).

    I’ve just developed this control as a temporary thing. It’s simply not intended to be used in a real production environment. Of course currently any Silverlight enabled site is just in Beta state as long as Silverlight itself is… So we can just hope that Microsoft also has recognized the issue and will close this gap as fast as possible…

  15. Christoph Husse said

    am April 11 2008 @ 1:40 am

    The InternationalTextBox will now also support the portuguese keyboard…
    If someone’s keyboard is still not supported just tell me the exact layout as stated in the windows language bar and I will try to create a proper keyboard class…

    regards
    chris

  16. Christoph Husse said

    am April 13 2008 @ 10:56 am

    A microsoft devloper just told me that this globalization issue will be fixed in Beta 2 and at last in the final version! So don’t worry…

  17. Dirk said

    am April 13 2008 @ 12:04 pm

    The Microsoft developers are incredibly reactive and open these days. These are very interesting times :-)

  18. Christoph Husse said

    am April 13 2008 @ 12:20 pm

    They would even do better to fix such issues before they arrive ;-)

  19. Weekly Links: Silverlight 2, ASP.NET MVC, .NET 3.5, jQuery, CSS, Powershell | Code-Inside Blog International said

    am April 14 2008 @ 5:37 am

    [...] Silverlight 2 (beta1): International (Non-US) TextBox [...]

  20. Silverlight Cream for April 9, 2008 - #247 said

    am April 16 2008 @ 11:27 am

    [...] Dan Wahlin on ItemsControl Templates and 3rdParty SL2 controls. From SilverlightCream.com: Silverlight 2 (beta1): International (Non-US) TextBox Michael Sync submitted this guest-post by Christoph Husse that is a very cool article on use of [...]

  21. Nuno Santos said

    am April 17 2008 @ 6:43 am

    I have tried the update to the international textbox. The portuguese works almost perfectly. There is a bug but i don’t know how to solve it.

    My way to write this “é” is to make ´ + e, however, this is working with the key on the left side, which is the key that has + and *. I think i just need to change the code, but i’m not sure which one is it.

  22. Christoph Husse said

    am April 17 2008 @ 7:00 am

    The key > ´ + < key, isn’t it? Is this your keyboard layout:

    http://en.wikipedia.org/wiki/Image:KB_Portuguese.svg

    ???

    I really don’t know why it shouldn’t work… I have tested this special characters! Maybe you just have a different layout!

    Please tell which keys you are pressing exactly, what you get and what you expect…

    regards
    chris

  23. Christoph Husse said

    am April 17 2008 @ 7:01 am

    Hmm something has gone wrong ^^… This should be the first sentence:

    The key > ´ + < key, isn’t it?

  24. Christoph Husse said

    am April 17 2008 @ 7:02 am

    hmmm… I probably invoked some internal bugs ^^… The first sentence won’t work so far ;-)… Just look at the layout and compare it to your keyboard!

  25. Nuno Santos said

    am April 17 2008 @ 7:56 am

    Yes, thats my layout.

    I think everything else works fine. I don’t know if the class i’m using was made by you. It was posted by someone in the silverlight forums:

    http://silverlight.net/forums/p/14053/47337.aspx#47337

    Regards,

    Nuno

  26. Christoph Husse said

    am April 17 2008 @ 8:03 am

    Yes it was made by me…

    Please tell me the PlatformKeyCode you get in Silverlight when pressing the “´” key on your keyboard. You get this code with a breakpoint in the KeyDown-Handler… It should be 187…

  27. Nuno Santos said

    am April 17 2008 @ 8:53 am

    No, ‘´’ its 186.

    The 187 key is the ‘+’ and ‘*’ key.

    Nuno

  28. Christoph Husse said

    am April 17 2008 @ 9:18 am

    Yes then goto “Windows latin char table” within your keyboard class and exchange 187 with 186 and 186 with 187 in Default, Shifted and Alted table…

  29. Nuno Santos said

    am April 17 2008 @ 9:21 am

    Done!!

    Thanks! ;)

    And congratulations for this wonderfull job! ;)

    Nuno

  30. Christoph Husse said

    am April 18 2008 @ 3:39 pm

    No problem at all ;-)

  31. Nuno Santos said

    am June 1 2008 @ 4:38 pm

    Hi,

    Do you have any report of problems using InternationalTextBox on mac osx?

    I cant type in this boxes on mac osx. I would like to know if you have any solution for this.

    Thx,

    Nuno

  32. Christoph Husse said

    am June 1 2008 @ 11:56 pm

    Yes, wait for Silverlight Beta 2 ;-)

    regards
    chris

  33. Michael Sync said

    am June 2 2008 @ 12:00 am

    >>wait for Silverlight Beta 2

    :) haha.. I think SL 2 beta2 should be released this week, man. seems it get delayed or something…

  34. Nuno Santos said

    am June 10 2008 @ 9:17 am

    Hi,

    Is there any update in mind for the international textbox for this beta 2?

    Thx,

    Nuno

  35. Michael Sync said

    am June 10 2008 @ 7:01 pm

    Hi Nuno,

    I think Chris will update the code but he mailed me once that he will be busy these days. Hopefully, he will migrate the code as soon as possible.

  36. Michael Sync said

    am June 11 2008 @ 6:09 am

    Hello Nuno,

    Chris mailed me the updated version of International Textbox. I have added it in this post. You may download the latest version now. Let us know if you have any problem with this version.

    (Thanks to Chris for updates)

  37. Nuno Santos said

    am June 11 2008 @ 11:22 am

    Hi,

    First of all, thank you Chris. Now, about the box, i can’t really tell. Backspace is working something that it wasn’t since beta 2 update. About writing in OSX I didn’t tried yet. And one more thing, as this class doesn’t bring the mappings to Portuguese i couldn’t use it in my project. Should i use the same class in other?

    What am i supposed to update?

    Thank you both,

    Nuno

  38. Christoph Husse said

    am June 11 2008 @ 11:27 am

    >Should i use the same class in other?

    Yes there are no code changes so far I think… I just recompiled the whole thing ^^!

    Maybe there are some small bugs but keep in mind that this is only a workaround. Dont worry about them, the final silverlight release will support all keyboards (or at least if Microsoft wants that Silverlight is not just some sort of faul shot).

    Before releasing any silverlight project to the general public you should wait for the final release in which you won’t need my control anymore!

  39. Nuno Santos said

    am June 11 2008 @ 3:23 pm

    Hi Chris,

    Your class is the salvation for now.

    Yeah, I now that the final release will have it, but how long it will take? 3 months? I can’t wait to release this until the final version.

    I need to have something online and your class does the job perfectly. I understand that you don’t want to wast your time in something that will be rubish in a couple of months.

    Maybe I will just need some tips in order to correct at is wrong.

    Right now just remember a couple of things:

    - Can’t delete (backspace) since beta 2
    - Password box doesn’t cleat on .Text = “”, it shows everything again when i use it again
    - Doesnt work on mac (i don’t know yet for the beta 2), still need to try it

    With a more extensive and dedicated review maybe I find some more.

    If you can help me, I’ll do the job.

    Thank you very much,

    Best regards,

    Nuno Santos

  40. Christoph Husse said

    am June 11 2008 @ 11:53 pm

    I did look at the code ;-):

    1) The first problem is solved by adding “e.Handled = false” to the second IF-statement of “ExtendedTextBox_KeyDown” like this:

    if (Value.Length == 0)
    {
    e.Handled = false;

    2) The second problem is just fine… You will have to clear the box over the password property. If you really need to do this over the text property (i wouldn’t know why) try to fix the “ExtendedTextBox_TextChanged” handler properly…

    3) As I don’t have a MAC, I can’t provide any help for you!

    regards
    chris

  41. Nuno Santos said

    am June 13 2008 @ 2:50 pm

    Hi Chris,

    Yeah, i forgot that exists an Password property.

    About the other problem:

    The e.Handle = false brought other problem, now the accents of my language such as ‘é’ doesn’t work very well. for example, if i write é the output is é´´

    Can you easily identify this problem?

    Thx,

    Nuno

  42. Nuno Santos said

    am June 13 2008 @ 2:57 pm

    Ah, and is also making the control raise a lot of exceptions basicly all related with SelectionStart property.

    Best regards,

    Nuno

  43. Christoph Husse said

    am June 13 2008 @ 10:48 pm

    Then you have to set “Handle = false” only if for the special cases BACKSPACE, DEL, HOME and so on…

  44. Nuno Santos said

    am June 20 2008 @ 9:24 am

    Hi Chris,

    I have a new issue.

    Can’t Ctrl+C and Ctrl+V.

    This ones are very usefull. What do i need to do in order to correct them?

    Thx,

    Nuno

  45. Nuno Santos said

    am June 27 2008 @ 2:09 am

    Hi,

    Sorry to bother you guys again. I don’t have Ctrl - C and Ctrl V working, and those are very usefull.

    They were working on the beta 1 release.

    What do i need in order to correct this? Can you give me a tip?

    Thx,

    Nuno

  46. Nuno Santos said

    am July 21 2008 @ 6:13 am

    Hi,

    Sorry for bothering you again Chris. I have just discovered that no final release will be out until the fall and i really need to have a website released.

    Your international textbox is being damn usefull. However there i on issue that you could help me getting to work again.

    Before beta 2 update, there was Ctrl + C & V support. Now it doesn’t work. I have been looking at the code but i couldn’t find anything related. Can you give me a tip here?

    Thx,

    Nuno

  47. Christoph Husse said

    am July 21 2008 @ 6:17 am

    Hi,

    looking at the code won’t do it.
    Set a breakpoint at the OnKeyDown event and try to find out what happens. I currently have no idea why it doesn’t work. I think I also tried it in the past and it doesn’t work…

    Sorry…

    regards
    chris

  48. Nuno Santos said

    am July 23 2008 @ 2:59 pm

    Hi Chris,

    I discovered something but without your help is kind of usefull i don’t understand the sequence of operations in the handling chain.

    OnKeyDown event starts this way:

    void ExtendedTextBox_KeyDown(object sender, KeyEventArgs e)
    {
    try
    {
    e.Handled = true;

    String Value = Keyboard.HandleKeyDown(sender, e);

    This way, it handles accents perfectly and doesn’t handle copy & past

    If i comment e.Handled = true, it doesn’t write the accents, instead it writes something like this for the letter ‘é’:

    ée´´

    And if write something like a simple letter ‘m’ and the output is:

    mm

    But the good thing is that it handles Ctrl + V.

    I believe that the absence of e.Handled makes the bubbling to continue until the top of the tree, which is the base class (please correct me if i’m completly wrong) which handles the ctrl + v, but also gives the normal output of the letters besides the one returned by your override with the correct accents.

    I just can’t find a way of doing a strategical cancel of the bubbling!

    I was hopping you could give me a tip here.

    Thank you very much and sorry for being such an headache for you,

    With my best regards,

    Nuno Santos

  49. Nuno Santos said

    am July 23 2008 @ 3:17 pm

    Hi Chris,

    I also discovered that is precisly that what is making the textbox not to work on mac.

    Thx,

    Nuno

  50. Christoph Husse said

    am July 23 2008 @ 11:36 pm

    Leave the code as it was originally and just return with “Handled=false”, if Ctrl is down and the current key is either V or C…

  51. Nuno Santos said

    am July 25 2008 @ 1:48 am

    Hi Chris,

    Thanks for your reply.

    What you suggested worked. However it is not working again since the modifications you suggested.

    I have created a project with two textboxes, one original and one of the yours.

    In mac, the original textbox works with accents! That’s very strange! Why it doesn’t work on windows as well?

    Well, it seems that make the textbox keydown e.Handled = false on ctrl + c or ctrl + v isnt enough to make it work on make.

    Maybe i should need to pass anything more that i don’t know.

    Or maybe i could just override everything when i’m on mac, which i don’t know how to do.

    Any tips?

    Nuno

  52. Christoph Husse said

    am July 25 2008 @ 2:00 am

    >Or maybe i could just override everything when i’m on mac, which i don’t know how to do.

    I don’t think that silverlight allows you to determine on which platform you are running. Also this is one of the goals silverlight has, to be platform independent.

    Wait for the final version…

  53. Christoph Husse said

    am July 25 2008 @ 2:03 am

    Well of course you can use javascript to detect the “safari” browser and then use the normal textbox instead. As my textbox is derived from “TextBox” there is no problem in implementing this switch.

    I think you can access javascript natively by using something that ends with “Browser.Windows.evaluate()”…

    regards
    chris

  54. Nuno Santos said

    am July 26 2008 @ 12:41 am

    Hi Chris,
    I have found a way of getting user agent string. This way i can get platform.

    Now i need you help to make the hack for the switch.

    This is what i have done:

    void ExtendedTextBox_KeyDown(object sender, KeyEventArgs e)
    {

    try
    {

    if (Page.platform == Platform.Windows)
    {
    e.Handled = true;
    String Value = Keyboard.HandleKeyDown(sender, e);

    ….

    }
    else
    {
    e.Handled = false;
    }
    }
    catch
    {
    }
    }

    It works but something is wrong because, now, the text is written this way. For example, if i write “this” the result will be

    “siht”

    Now i need to put all togheter in order to have it working on mac, windows and with ctrl-c and ctrl-v working.

    Which HandleKeyDown should i mess with? In which class?

    Its almost there! :)

    Thanks for your time and patience!

    Best regards,

    Nuno

  55. Christoph Husse said

    am July 26 2008 @ 1:11 am

    If the platform is Mac you should skip the whole constructor… So that the TextBox is just a normal TextBox…

  56. Nuno Santos said

    am July 26 2008 @ 1:55 am

    That way doesnt work in mac. Nothing.

    This is what i have done in the constructor

    if (Page.platform == Platform.Windows)
    {
    KeyDown += new KeyEventHandler(ExtendedTextBox_KeyDown);
    KeyUp += new KeyEventHandler(ExtendedTextBox_KeyUp);
    TextChanged += new TextChangedEventHandler(ExtendedTextBox_TextChanged);
    SelectionChanged += new RoutedEventHandler(ExtendedTextBox_SelectionChanged);

    try
    {
    IsolatedStorageFile File = IsolatedStorageFile.GetUserStoreForApplication();
    IsolatedStorageFileStream Stream = File.OpenFile(”InternationalTextBox.keyboard.layout”, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

    using (Stream)
    {
    BinaryReader Reader = new BinaryReader(Stream);
    String Selection = Reader.ReadString();

    for (int i = 0; i < TextBoxKeyboard.Keyboards.Length; i++)
    {
    if (TextBoxKeyboard.Keyboards[i].Description.CompareTo(Selection) == 0)
    {
    m_Keyboard = TextBoxKeyboard.Keyboards[i].CreateInstance();

    break;
    }
    }
    }
    }
    catch
    {
    m_Keyboard = new US_Keyboard();
    }
    }

    Any thing missing?

    Thx,

    Nuno

  57. Christoph Husse said

    am July 26 2008 @ 12:43 pm

    >In mac, the original textbox works with accents!

    So I don’t see the problem…

    If you don’t execute the constructor in mac, my textbox is simply a usual textbox, so it should work!

  58. Nuno Santos said

    am July 26 2008 @ 4:17 pm

    Chris,

    Sorry, but i don’t know any other way of using your textbox without manually instanciate a variable of InternationTextBox type, initialize it with the constructor and manually add it to the UI like this:

    emailTextBox = new InternationalTextBox();
    emailTextBox.Keyboard = new Portuguese_Keyboard();
    emailTextBox.AcceptsReturn = true;
    emailTextBox.Width = 150;
    emailTextBox.Height = 110;
    emailTextBox.Margin = new Thickness(5, 5, 0, 5);
    emailTextBox.Padding = new Thickness(0, 0, 0, 0);
    emailTextBox.HorizontalAlignment = HorizontalAlignment.Left;
    emailTextBox.VerticalAlignment = VerticalAlignment.Bottom;
    emailTextBox.BorderThickness = new Thickness(0);
    emailTextBox.FontSize = 10;

    LayoutRoot.Children.Add(emailTextBox);

    I have already tried to instanciate it in xaml without any success. That would be wonderfull for me as i could have much less code.

    I tried like this, but silverlight explodes and nothing appears:

    xmlns:sda=”clr-namespace:SDA.SL.UI”

    So, what i understood from your tip was to avoid everything in the InternationTextBox constructor while in mac.

    Can you please be more specific? As i’m not understanding you.

    Thank you,

    Best regards,

    Nuno

  59. Christoph Husse said

    am July 26 2008 @ 11:01 pm

    if(IsMac)
    {
    emailTextBox = new TextBox();
    }
    else
    {
    emailTextBox = new InternationalTextBox();
    }

    You can make initialization short by using constructors with more parameters like that:

    emailTextBox = new InternationalTextBox(true, 150, 110, …);

    For XAML you could try to derive a component from “UserControl” and provide the above switch in the constructor, maintaining a “private TextBox Surface;” member which actuallly represents the content of your user control. Then just export all the member you need by prototyping them like:

    Color BackgroundColor
    {
    get{return Surface.BackgroundColor;}
    set[Surface.BackgroundColor = value;}
    }

  60. Nuno Santos said

    am July 28 2008 @ 12:46 pm

    Hi Chris,

    I have done this:

    public InternationalTextBox()
    {
    if (System.Environment.OSVersion.Platform != PlatformID.MacOSX)
    {
    KeyDown += new KeyEventHandler(ExtendedTextBox_KeyDown);
    KeyUp += new KeyEventHandler(ExtendedTextBox_KeyUp);
    TextChanged += new TextChangedEventHandler(ExtendedTextBox_TextChanged);
    SelectionChanged += new RoutedEventHandler(ExtendedTextBox_SelectionChanged);

    try
    {
    IsolatedStorageFile File = IsolatedStorageFile.GetUserStoreForApplication();
    IsolatedStorageFileStream Stream = File.OpenFile(”InternationalTextBox.keyboard.layout”, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

    using (Stream)
    {
    BinaryReader Reader = new BinaryReader(Stream);
    String Selection = Reader.ReadString();

    for (int i = 0; i < TextBoxKeyboard.Keyboards.Length; i++)
    {
    if (TextBoxKeyboard.Keyboards[i].Description.CompareTo(Selection) == 0)
    {
    m_Keyboard = TextBoxKeyboard.Keyboards[i].CreateInstance();

    break;
    }
    }
    }
    }
    catch
    {
    m_Keyboard = new US_Keyboard();
    }
    }
    }

    Basicly its the same thing i tried the first time. It’s working. maybe there was some gap in my testing.

    I prefer this way because it will not implicate breaking changes in the rest of the code.

    Thank you for your patient and help.

    Best regards,

    Nuno

  61. Christoph Husse said

    am July 28 2008 @ 12:51 pm

    I am happy that it works now…

    Well you changed a significiant part! Now you check whether the OS is NOT mac whereas you previously checked whether the OS is windows.

    So I assume that your OS determination provided wrong results…

    regards
    chris

  62. Michael Sync » Silverlight 2 beta2 - Samples Updated said

    am August 4 2008 @ 12:36 am

    [...] Silverlight 2 (beta1): International (Non-US) TextBox (By Chris) [...]

  63. quintorel said

    am August 13 2008 @ 12:58 pm

    Hi,

    I detect a bug in InternationalTextBox class:

    void ExtendedTextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
    if (m_SelectionIndex < 0)
    SelectionStart = 0;
    else
    SelectionStart = m_SelectionIndex;
    }

    On TextChanged methos we have to control if m_SelectionIndex is less than zero.
    Sometimes fail it, if don’t control.

    For Example. Write in TextBox “Hi, my name is Jose” and with the mouse put the cursor in comma and Back(remove) “Hi,”, just then press DELETE and fail.

    Regards!!!

  64. quintorel said

    am August 13 2008 @ 2:03 pm

    Hi,

    with this code I achieve that works ctrol+c ctrol+v and ctrol+x:

    void ExtendedTextBox_KeyDown(object sender, KeyEventArgs e)
    {
    e.Handled = true;

    String Value = Keyboard.HandleKeyDown(sender, e);

    //if (AcceptTabs && (e.Key == Key.Tab))
    //{
    // Value = “\t”; // a plain tab is not displayed correctly, so we use multiple spaces…

    // Focus();
    //}

    //Si es una tecla especial (Por aqui tb pasan las de los acentos)
    if (Value.Length == 0)
    {
    //Switch es la forma más eficiente de hacer esto
    switch (e.Key)
    {
    case Key.Delete:
    {
    e.Handled = false;
    break;
    }
    //Inicio
    case Key.Home:
    {
    e.Handled = false;
    break;
    }
    case Key.PageDown:
    {
    e.Handled = false;
    break;
    }
    case Key.PageUp:
    {
    e.Handled = false;
    break;
    }
    case Key.End:
    {
    e.Handled = false;
    break;
    }
    case Key.Left:
    {
    e.Handled = false;
    break;
    }
    case Key.Right:
    {
    e.Handled = false;
    break;
    }
    case Key.Down:
    {
    e.Handled = false;
    break;
    }
    case Key.Up:
    {
    e.Handled = false;
    break;
    }
    //Hay que poner esto para que se lancen los eventos del intro
    case Key.Enter:
    {
    e.Handled = false;
    break;
    }
    case Key.Back:
    {
    e.Handled = false;
    break;
    }
    case Key.Insert:
    {
    e.Handled = false;
    break;
    }
    case Key.Escape:
    {
    e.Handled = false;
    break;
    }
    //Necesario
    case Key.Space:
    {
    e.Handled = false;
    break;
    }
    //Necesario para que funcione el TAB
    case Key.Tab:
    {
    e.Handled = false;
    break;
    }
    //Para Ctrl+C Ctrol+V Ctrol+X
    //case Key.Ctrl:
    // {
    // e.Handled = false;
    // break;
    // }
    case Key.C:
    {
    e.Handled = false;
    break;
    }
    case Key.X:
    {
    e.Handled = false;
    break;
    }
    case Key.V:
    {
    e.Handled = false;
    break;
    }

    }

    if ((e.Key == Key.Back) && (m_SelectionLength < 1))
    m_SelectionIndex–;

    if (IsPassword)
    {
    // handle selection removal of more than one character per time…
    if (Text.Length < m_Protected.Length)
    {
    m_Protected = m_Protected.Substring(0, m_SelectionIndex) +
    m_Protected.Substring(m_SelectionIndex + Math.Max(1, m_SelectionLength));

    m_SelectionIndex = Math.Min(m_SelectionIndex, Text.Length);
    m_SelectionLength = 0;
    }
    }

    return;
    }

    UpdateText(Value);
    }

    Practically, i have do the next:

    if (Value == “”) and (Key == V) is because the key “V” don’t produce values and is because any other key is pressed.
    In this case, e.Handled = false.
    And copy, cut and paste perfectly.

    Only there are any bug, that the cursor don’t go to the final of the pasted text, it stay at start of the text pasted.

    Any suggest Chris??

    Thanks

  65. Presad Pathak said

    am August 27 2008 @ 6:57 am

    Hi, All
    I am using this international text box in my app…….
    - I am not able to use delete key when if i select with shift key pressed and then delete key presses not deleting ……
    - Not working on mac and if i want that text box to be used for password …..

    Will any one suggest me ……. its urgent……

    Thanx in advance……..

Comment RSS · TrackBack URI

Leave a comment

Name: (Required)

eMail: (Required)

Website:

Comment: