Click here to Skip to main content
15,879,535 members
Articles / Programming Languages / C#

Silverlight:SetTextBoxFocusUsingMVVM

Rate me:
Please Sign up or sign in to vote.
4.80/5 (12 votes)
19 Sep 2010CPOL3 min read 42.4K   662   8   7
How to set focus inside textbox while validating using MVVM pattern

Introduction

The MVVM is an architectural pattern from Microsoft. View Class has no idea about model exist however viewmodel and model don’t know about view. It is a loosely coupled design.
This separates the role of designer to focus on UI instead of programming/business logic and allows application to work in different work streams.

MVVM_Architecture.jpg

If interested, get more details on 5 Minute Overview of MVVM in Silverlight.

This article explains the problem of how to set focus inside textbox(View) when we use validation logic when using MVVM pattern.

Background

One of my friends had given me a problem and asked me for a solution which I feel is required by most developers, so I decided to write an article on this which might be helpful.
As it is a general scenario that an application has some control (Textbox) which needs input from the end user and when end user performs some action (Save or move to another form), we do validation on button click. Now in Silverlight, with the help of ValidatesOnDataErrors=True attribute display UI with red border outside textbox which indicates required field/invalid data. You can see in the below Screen 1 and Screen 2.

Normal.jpg

NoFocusInside_TextBox.jpg

However, it would be good if it will blink cursor inside the textbox so that user does not need to explicitly click mouse to set focus inside textbox after which only he/she can enter input.
So the point of interest here is to achieve this using MVVM model without writing any code in View code-behind file.
The below screen 3 explains more:

Focus_Inside_TextBox.jpg

Using the Code

Currently Silverlight 4.0 doesn’t provide directly CommandManager, with the help of how to Creating a command manager in Silverlight as this command manager will be implemented in View which will bind the command of button with click event.

XML
<Button Content="Click!"="3"Grid.Column="2"Grid.ColumnSpan="2"
Cmd:CommandManager.CommandEventName="Click"
Cmd:CommandManager.Command="{Binding ClickCommand }" />

As currently this CommandManager is created as a separated library which can be used across any other Silverlight class library.

Class TextBoxAttach

Now define a class name as TextBoxAttach which has Dependency property (TextBoxControllerProperty). This property registers a function OnTextBoxControllerChanged which will execute whenever the textbox control loads. The important point in the below code is when this property has been attached to textbox, then it has one dictionary being defined called elements1 which stores the textbox name as ID.

XML
private static readonly Dictionary<string,TextBox> elements1 = 
				new Dictionary<string,TextBox>();

private static void OnTextBoxControllerChanged
	(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var element = d as TextBox;
if (element == null)
throw new ArgumentNullException("d");
var newController = e.NewValue as ITextBoxController;
if (newController != null)
{
elements1.Add(element.Name, element);
newController.ClickButton += ClickButton;
}
}

Now when you click on Button, the ClickButton event fires which checks if textbox is empty to those textboxes which have been attached with TextBoxControllerProperty and it will set the focus inside textbox.

XML
private static void ClickButton(ITextBoxController sender)
{
foreach (KeyValuePair<string,TextBox> pair in elements1)
{
TextBox element;
string key = pair.Key;
element = pair.Value;
if (string.IsNullOrEmpty(element.Text))
{
element.Focus();
break;
}
}
}

So to use this TextBoxAttach to set focus inside a textbox, the XAML code will be something like this:

XML
<TextBox x:Name="textBox1" loc:TextBoxAttach.TextBoxController="{Binding}" /> 

Class MyViewModel

Class MyViewModel inherits from ITextBoxController and uses event ClickEventhandler which is defined in ITextBoxController. And here in the constructor of MyViewModel initialize the ClickCommand with the help of RelayCommand which itself inherits from ICommand.

C#
public MyViewModel()
{
Value1 = "My Text1";
Value2 = "My Text2";

ClickCommand = new RelayCommand(p =>
{
if (ClickButton != null)
ClickButton(this);
});
}

Now to display validation error UI to view MyViewModel class also inherits from IDataErrorInfo which implements the indexer also known as smart arrays in C#. It is pretty much like defining properties:

C#
public string this[string columnName]
{
get 
{
string strMessage = string.Empty;
CustomValidation(ref strMessage, columnName);
return strMessage;
}
}

And to use this validation feature, the XAML code will be like this:

XML
<TextBox x:Name="textBox1" Text="{Binding Path=Value1,
Mode=TwoWay,ValidatesOnDataErrors=True}" /> 

Points of Interest

  1. MVVM- How can I select text in a textbox?
  2. Model-View-ViewModel In Silverlight Apps.

Finally

As there is always scope for improvement, it would be good if you have any comments/complaints/suggestions, kindly let me know. I will try to address those points and your feedback will help me to improve my future articles on CodeProject J.

History

  • Posted on 18-Sep-2010

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionHow we can generalize the solution ? Pin
Member 24477226-Apr-12 21:04
Member 24477226-Apr-12 21:04 
GeneralMy vote of 5 Pin
Kunal Chowdhury «IN»13-Jan-11 17:01
professionalKunal Chowdhury «IN»13-Jan-11 17:01 
GeneralGreat job! Pin
Maze14-Oct-10 8:00
Maze14-Oct-10 8:00 
GeneralMy vote of 5 Pin
Pravin Saindane21-Sep-10 3:16
Pravin Saindane21-Sep-10 3:16 
GeneralRe: My vote of 5 Pin
Anil_Saran21-Sep-10 18:13
Anil_Saran21-Sep-10 18:13 
GeneralMy vote of 5 Pin
SureshGubba19-Sep-10 23:04
SureshGubba19-Sep-10 23:04 
GeneralRe: My vote of 5 Pin
Anil_Saran21-Sep-10 18:14
Anil_Saran21-Sep-10 18:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.