Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

UWP TextBox Behaviour for Focus & Command Binding

0.00/5 (No votes)
24 Mar 2016 1  
Adds MVVM focusing and command execution on keypress to universal Windows platorm textbox via attached properties.

Introduction

This is a behaviour class that you can plug into your universal Windows platform to provide a means of focusing a textbox in an MVVM fashion and also provides the ability to execute a command based on a key press.

Background

See the following article for an introduction to the concept of attached behaviours:

Using the Code

The behaviour class provides two features.

Focus

The focusing capabilities have the following elements.

First, an attached property to indicate if the control has focus or not.

C#
/// <summary>
/// Declare new attached property.
/// </summary>
public static readonly DependencyProperty IsFocusedProperty =
      DependencyProperty.RegisterAttached("IsFocused", typeof(bool),
      typeof(TextBoxBehaviour), new PropertyMetadata(default(bool), OnIsFocusedChanged));

When the IsFocused property is changed, the OnIsFocusedChanged method will be called. Within the method; if the IsFocused property is true, then the control is Focused. Additionally, handling is attached for the LostFocus event.

C#
/// <summary>
/// This method will be called when the IsFocused
/// property is changed
/// </summary>
/// <param name="s">System.Object repersenting the source of the event.</param>
/// <param name="e">The arguments for the event.</param>
public static void OnIsFocusedChanged(DependencyObject s, DependencyPropertyChangedEventArgs e)
{
    //If the host object is a frame.
    if (s is TextBox)
    {
        //Unbox.
        TextBox t = s as TextBox;

        //If setting is true.
        if ((bool)e.NewValue)
        {
            //Set the Focus
            t.Focus(FocusState.Pointer);

            //Attach handling for lost focus.
            t.LostFocus += textbox_LostFocus;
        }
        else
        {
            //Remove handling.
            t.LostFocus -= textbox_LostFocus;
        }
    }
}

Inside the LostFocus event, the property is reset.

C#
/// <summary>
/// Handling for when the texbox looses focus.
/// </summary>
/// <param name="sender">System.Object repersenting the source of the event.</param>
/// <param name="e">The arguments for the event.</param>
private static void textbox_LostFocus(object sender, RoutedEventArgs e)
{
    //Unbox.
    TextBox t = sender as TextBox;

    //Set dependency property.
    t.SetValue(IsFocusedProperty, false);
}

In your view, add the namespace for the behaviour.

XML
xmlns:behave="using:UtilitiesUniversal.Behaviours"

You could then use the attached property as follows. Note that I have binded the property to the check state of a toggle button element placed elsewhere on the page. Now the focus of the control is toggled along with the toggle button checkstate. A potentially useful feature for one handed use on mobile.

XML
<TextBox Name="filterText" 
behave:TextBoxBehaviour.IsFocused="{Binding ElementName=filterBtn, 
Path=IsChecked, Mode=TwoWay}" Height="48"   
InputScope="AlphanumericFullWidth" 
VerticalContentAlignment="Center" FontSize="25" >

...

 <CommandBar ClosedDisplayMode="Compact" Name="commands">
                <AppBarToggleButton Icon="Filter" 
                x:Uid="Filter" Name="filterBtn" IsChecked="False"/>
  </CommandBar>       

Command Binding

The other feature provided by the behaviour class is for executing a command on a keypress.

The command binding feature has the following elements.

First, there is the property to house the desired command.

C#
public static readonly DependencyProperty CommandProperty =
            DependencyProperty.RegisterAttached("Command", typeof(ICommand),
                typeof(TextBoxBehaviour), new PropertyMetadata(null));     

The other property is of course the desired key that will trigger the command.

C#
public static readonly DependencyProperty CommandKeyProperty =
    DependencyProperty.RegisterAttached("CommandKey", typeof(string),
    typeof(TextBoxBehaviour), new PropertyMetadata(default(string), OnCommandKeyChanged));

In the OnCommandKeyChanged, Callback handling is attached for the KeyDown event.

C#
private static void OnCommandKeyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
       {
           if (d is TextBox)
           {
               //Unbox.
               TextBox t = d as TextBox;


               //If the key is set.
               if (e.NewValue != null && e.NewValue.ToString().Length > 0)
               {
                   t.KeyDown += T_KeyDown;
               }
               else
               {
                   t.KeyDown -= T_KeyDown;
               }
           }
       }

In the KeyDown event handler, the pressed key is compared to the CommandKey property and if it matches, the command is executed.

C#
private static void T_KeyDown(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
       {
           TextBox t = sender as TextBox;

           if (e.Key.ToString() == t.GetValue(CommandKeyProperty).ToString())
           {
               //Handle.
               e.Handled = true;

               // Get command
               ICommand command = GetCommand(t);

               // Execute command
               command.Execute(null);
           }
       }

In your view, add the namespace for the behaviour:

XML
xmlns:behave="using:UtilitiesUniversal.Behaviours"

Now, you can use the property as follows; In the example, I will execute the ReadCommand in the current datacontext when the enter button is pressed in the textbox.

XML
<TextBox AcceptsReturn="False" 
behave:TextBoxBehaviour.Command="{Binding ReadCommand}" 
behave:TextBoxBehaviour.CommandKey="{Binding FakeBinding,FallbackValue=Enter}"  
InputScope="AlphanumericFullWidth" 
VerticalContentAlignment="Center" FontSize="25"/>

Points of Interest

It is my experience that the universal Windows platform will not allow setting an attached property directly, i.e., you must use a binding. Hence the binding notation above.

History

  • 1.0

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here