Virtual Input Keyboard & Behaviours for Silverlight

Posted by Rishi on 09-Nov-09 9:04 AM - Comments (19)

You would already know this, but in Silverlight when in full-screen mode keyboard input is by design constrained to a limited set of keys - this often takes an end-user by surprise and leaves them with a perception than it's an application problem. To overcome this Silverlight limitation I've created a Virtual Input Keyboard and accompanying behaviours, that allows you to attach an on-screen keyboard to any receptive UI control.

VirtualInputKeyboard

View the demo app here.

The Input Keyboard

It is important to appreciate that the Silverlight Keyboard presented here is an Input Keyboard, which is different from a general purpose Virtual Keyboard found in most Operating Systems. The input keyboard is specifically only made visible on-screen when directly editing/inputting to an attached UI control (e.g. a TextBox), when not editing/inputting it is automatically hidden from view - this is very much like in mobile phones. So for example with the PasswordBox shown above the Input Keyboard will be made visible when the PasswordBox has focus, and in the "focus" state it allows you to "key-in" characters but anytime the PasswordBox looses the focus the keyboard also vanishes.

 K for Keyboard

Symbols Keys

Key Features

  • All character-keys feature iPhone'que callouts/popouts when pressed
  • A symbols mode (bottom right key) features most of the commonly used symbol and non-alphabetic characters (shown above) - however currently there is no support for customizing or appending custom symbols
  • There is a sticky shift-key (bottom left) that allows for capitalized alphabets
  • The keyboard also allows for a Title, above it is set to "User Password"
  • The keyboard is collapsable, see the arrow key show above (top right)
  • The keyboard is dragable, and is not constrained to its parent's bounds
  • The keyboard is based on the Popup Primitive in Silverlight, so it is not effected by z-index based layering
  • A single keyboard control instance can be registered and used throughout the application as the default keyboard
  • You avail the keyboard by attaching behaviours to UI controls, included are behaviours for attaching to a Textbox or a PasswordBox control
  • You can create custom behaviours to consume the Keyboard with other kinds of UI controls such as a Grid or ListBox (I will post separately about how to do this)
  • The behaviours also allow you to configure as to if the Keyboard is only available when in full-screen mode (the default setting)

Behaviours

Like I mentioned included are three behaviours based on the Blend SDK, which allow you the configure and attach the Keyboard with various UI controls.

ApplicationInputKeyboardBehavior

You put this behaviour onto an Input Keyboard, and it makes it the default application-wide keyboard for use by one or more UI controls. Without this, you'll need to specify onto each attached control the keyboard you want to use it. Further, to make life easy it has no configurable settings, so simply drag and drop this onto an Input Keyboard.

TextBoxInputKeyboardBehavior TextBoxInputKeyboardBehavior

This behaviour is applied onto a TextBox, and it in turn attaches a Keyboard onto it. Using this behaviours is very simple, it has three properties - one to specify the Title that is shown atop the Keyboard (note its use is optional). The second property, takes in the Target Keyboard name, as shown in the screenshot on your right. However, if you wanted to use the default application wide keyboard (as described above), then you leave this empty and it will resolve it automatically. Lastly, the VisibleInNonFullScreenMode property, allows the Keyboard to be visible when not in full-screen mode. Note again, the default behaviour will only show the keyboard when in full-screen mode, so turn this on if you want it available independent of the full-screen mode.

PasswordBoxInputKeyboardBehavior

As the name suggests this behaviour is applicable to PasswordBox controls, and the use API is identical to the TextBoxInputKeyboardBehaviour. However, the use-semantics are quite different - the TextBox keyboard behaviour can identify and use text-selection and cursor position information, and therefore the interaction with the Input Keyboard fully mimics the use-semantics we are accustomed too with a physical keyboard and mouse. Now, the PasswordBox control doesn't expose text-selection or cursor position information, which leads to somewhat counter-intuitive use interaction. For example, if you've partially selected some part of the password text and press a key with your physical keyboard it would overwrite the selection with the keyed character. However, with the Virtual Input Keyboard you can only append any keyed character to the end of the password string, because we are not party to selection or cursor-position information with the PasswordBox control. Also the automation API in Silverlight suffers from the same information deficiencies, which is why I've forgone its use.

Future Enhancements

Since this is just the first shot at this, there are plenty of possible enhancements. Some of the ones I am considering are:

  • Customizable key-sets, using predefined profiles - kind of like how iPhone offers a different key-set for entering Urls
  • An optional default action key, like one to trigger a "Google" - this is also akin to iPhones
  • Key press sounds option
  • Configurable relative positioning of Keyboard to any attached UI control
  • A numeric-pad version of the Input Keyboard, that only offers numeral characters
  • Templat'able Keyboard and Keys UI
  • A sharper/better default skin

If you have any other suggestions or ideas, do let me know.

You can download the Input Keyboard dll (16 kb) from the Expression Gallery Site,
and again you can view the demo app here.

UPDATE (17-Dec):

The following are two classes that allow you to attach the Keyboard to an AutoCompleteBox Control (found in Silverlight Toolkit). However do note that the AutoCompleteBox does not expose selection information so the keys are added and removed from the end of the text-string only - which unfortunately is not all that intuitive.

   1: // Keyboard Input Handler for AutoCompleteBox
   2: public class AutoCompleteBoxInputHandler : IInputKeyboardHandler
   3: {
   4:     
   5:     readonly AutoCompleteBox _autoCompleteBox;
   6:     
   7:     public event EventHandler InputKeyboardAttached;
   8:     public event EventHandler InputKeyboardDetached;
   9:  
  10:     public AutoCompleteBoxInputHandler(AutoCompleteBox autoCompleteBox)
  11:     {
  12:         if (autoCompleteBox == null) throw new ArgumentNullException("autoCompleteBox");
  13:         _autoCompleteBox = autoCompleteBox;
  14:     }
  15:     
  16: #region IKeyboardHandler Implementation
  17:     
  18:     public void KeyboadAttached() 
  19:     { 
  20:         if (InputKeyboardAttached != null) 
  21:             InputKeyboardAttached(this, EventArgs.Empty);
  22:     }
  23:         
  24:     public void KeyboardDetached() 
  25:     { 
  26:         if (InputKeyboardDetached != null) 
  27:             InputKeyboardDetached(this, EventArgs.Empty);            
  28:     }
  29:     
  30:     public void CharacterKeyed(Char character)
  31:     {
  32:         // we append to the end the added character, also notice there is no max length on auto-complete
  33:         _autoCompleteBox.Text = _autoCompleteBox.Text + character.ToString();
  34:     }
  35:     
  36:     public void BackspaceKeyed()
  37:     {
  38:         // we remove one letter from the end
  39:         var _existingText = _autoCompleteBox.Text;
  40:            if (_existingText.Length > 0)
  41:             _autoCompleteBox.Text = _existingText.Substring(0, _existingText.Length - 1);    
  42:     }
  43:     
  44: #endregion
  45:     
  46: }
  47:  
  48: // Behaviour Class to Attach to AutoCompleteBox
  49: public class AutoCompleteBoxKeyboardBehavior : InputKeyboardBehaviorBase<AutoCompleteBox>
  50: {
  51:     
  52: #region Override
  53:  
  54:     protected override IInputKeyboardHandler ResolveKeyboardHandler()
  55:     {
  56:         return new AutoCompleteBoxInputHandler(this.AssociatedObject);
  57:     }
  58:     
  59:     protected override void OnAttached()
  60:     {
  61:         base.OnAttached();
  62:         
  63:         // we attach to the textbox
  64:         AssociatedObject.GotFocus += new System.Windows.RoutedEventHandler(AssociatedObject_GotFocus);
  65:         AssociatedObject.LostFocus += new System.Windows.RoutedEventHandler(AssociatedObject_LostFocus);
  66:     }
  67:     
  68:     protected override void OnDetaching()
  69:     {
  70:         base.OnDetaching();
  71:         
  72:         // detach the handlers
  73:         AssociatedObject.GotFocus -= new System.Windows.RoutedEventHandler(AssociatedObject_GotFocus);
  74:         AssociatedObject.LostFocus -= new System.Windows.RoutedEventHandler(AssociatedObject_LostFocus);
  75:     }
  76:  
  77: #endregion
  78:  
  79: #region Handler
  80:  
  81:     void AssociatedObject_GotFocus(object sender, RoutedEventArgs e)
  82:     {
  83:         base.AttachToKeyboard();
  84:     }
  85:     
  86:     void AssociatedObject_LostFocus(object sender, RoutedEventArgs e)
  87:     {
  88:         base.DetachFromKeyboard();
  89:     }
  90:     
  91: #endregion
  92:     
  93: }

Also remember, you can create IInputKeyboardHandler implementation along with a matching Behavior for other types of input controls you require.

Comments

trackback
DotNetShoutout
on 27-Oct-09 4:33 PM
Virtual Input Keyboard & Behaviours for Silverlight

Thank you for submitting this cool story - Trackback from DotNetShoutout

trackback
DotNetKicks.com
on 27-Oct-09 4:36 PM
Virtual Input Keyboard

You've been kicked (a good thing) - Trackback from DotNetKicks.com

pingback
vincenthomedev.wordpress.com
on 31-Oct-09 3:08 AM
Pingback from vincenthomedev.wordpress.com

Full-screen Mode Virtual Input Keyboard for Silverlight « Vincent Leung's .NET Tech Clips

pingback
stevepietrek.com
on 31-Oct-09 4:08 PM
Pingback from stevepietrek.com

Links (11/12/2009) « Steve Pietrek – Everything SharePoint

veer
veer India
on 05-Nov-09 7:27 PM
HI,

How to use Orktane.Keyboard.dll, i refrenced it in the project, when i uses any behaviour, application raises an error. what does Target keyboard proerty is for ? can you upload a sample project solution.

Shirley
Shirley United States
on 09-Nov-09 1:55 AM
I was wondering if it was possible to resize the width and height of the keyboard? I tried to set the properties on it but it won't budge. Is there a special property?

Rishi
Rishi
on 09-Nov-09 2:45 AM
@Shirley, sorry the width and height are fixed and since the keyboard is setup as a popup, setting the width/height of the host control wouldn't effect it. However, I am sure about this, but you might be able to scale transform the keyboard by applying it to the host control.

Hope that helps.

Kinlars
Kinlars Norway
on 28-Nov-09 1:50 PM
It doesn't seem to work in anything else than a UserControl. It won't work in a navigation page, or SilverlightFX windows.

Rishi
Rishi
on 28-Nov-09 9:02 PM
@Kinlars, I hope you do know that Navigation Pages and Windows both maintain their own element naming scopes. So if you are referring to a Keyboard instance (by name) outside their scope it wouldn't work. In such a case you need to use ApplicationInputKeyboardBehavior onto the Keyboard and the Keyboard should be placed in the RootVisual (or elsewhere where it will be available for the lifetime of the app). Once an application-wide Keyboard is specified, then also don't specify the Target Keyboard on the TextBoxInputKeyboardBehavior or PasswordInputKeyboardBehavior as it will pick up the app-wide one. That should work, if not then you'll need to show me the specific code-example where it doesn't.

Antonio Dias
Antonio Dias Portugal
on 08-Dec-09 3:18 AM
First, congrats! Very nice control and i got it working very well.
Second, i'd really like to request some changes:
- Could you add a close/hide button to the control instead of only the "minimize"?
- An "Return" key would also be a nice addition
- The numeric only would be a really nice thing ;)

If you don't have time, i could implement some of this changes and send it to you!

Thanks

Antonio Dias
Antonio Dias Portugal
on 08-Dec-09 3:38 AM
By the way, i'm using an AutoCompleteBox from the Silverlight Toolkit. Any chance that you could add support for it?

Thanks

Rishi
Rishi
on 09-Dec-09 6:19 AM
@Antonio thanks. Firstly, about the changes I am not in favor of the closing/hiding the keyboard thing as once closed one would have to de-focus from the input control and then re-focus again to show up. I want the keyboard to be automatically availed kinda like in smartphones.

As for the Return key, I should have added it to support multi-line text input. However, what I'll do is update the control to support custom "key-set" profiles and put it on Codeplex - from where you can implement and submit changes. I've already got requests for non-English characters so that would also be possible there. In the meantime, I've added code to allow attaching to AutoCompleteBox control, hope that helps.

Antonio Dias
Antonio Dias Portugal
on 09-Dec-09 5:33 PM
Thank you for the quick reply.

I understand the problem with the close button, i asked because in the application i'm building there's a "Page" that only has a TextBox and so to hide the keyboard i have to press the Tab key on my real keyboard to de-focus the TextBox but the real keyboard might not be present (touch-screen interface). Unless i'm missing something..

Rishi
Rishi
on 10-Dec-09 4:55 AM
Well a simple solution would be to de-focus the text-box when IsCollapsed property of the InputKeyboard is set to true - see ValueTriggers in nRoute.Toolkit(.) But, just so that you can customize exactly to your needs, I'll send you the code to your given mail address. Hope that helps.

rlodina
rlodina Romania
on 01-Jan-10 11:15 AM
Hi Rishi,

The on-line demo return error:
Webpage error details

User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Tablet PC 2.0; InfoPath.2; MS-RTC LM 8; .NET4.0C; .NET4.0E)
Timestamp: Wed, 6 Jan 2010 07:14:21 UTC


Message: Unhandled Error in Silverlight Application
Code: 2103    
Category: InitializeError      
Message: Invalid or malformed application: Check manifest    

Line: 53
Char: 13
Code: 0
URI: http://www.orktane.com/Labs/InputKeyboard/


Thank you

Rishi
Rishi
on 01-Jan-10 7:18 PM
@Rlodina, thanks for that tip - don't know what happened, but I've just updated it n' it seems to working fine now. Cheers.

Carlos Guevara
Carlos Guevara Panama
on 30-Jan-10 7:19 PM
Hello.  This is great work, congratulations.

I see that you are thinking about putting this wonderful keyboard up on codeplex, any idea when you might do that with the enhancements (skinning, etc.)??

My main problem with the keyboard was addressed recently in a post, because using the keyboard inside a PAGE (for navigation purposes) gives error in the PARSER when you add properties like TargetKeyboard or try to set it to be visible when non-full screen.  Using the applicationKeyboard behavior works, but it looks like it limits me to use the keyboard in ONE position for the whole application, but I can't tell if you can change the position (so that it does not cover other controls in certain windows, etc.).

Can you suggest a solution for my problem??? Thanks and again congratulations on an amazing control!

mundl
mundl Switzerland
on 02-Feb-10 10:44 AM
great work...
do you work on future enhancements?
or do you plan to publish the code?
so i can work for myself on future enhancements and realize my additional ideas.
    

Rishi
Rishi
on 05-Feb-10 3:23 AM
@Carlos, I am looking to do it within the month, I've created a Codeplex project called SLIK (stands for Silverlight Input Keyboard) and hope to get it started there. Now, about the moving thing, I'll check on it and come back to you. Plus the problem with navigation pages is not related to the Keyboard control but the naming scope of objects in Silverlight - a navigation page has its own naming scope.

@Mundl Like I said I'm putting it up on Codeplex, I wanna do some ground work first and then open it up. Further, I wanna provide multilingual support, so I need people from various language-speaking backgrounds if possible. If you are keen to help, then provide me with your Codeplex handle and I can add you to the project.

Cheers.

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading