






One of the pain points in MVVM development is controlling input focus from ViewModel objects. A common scenario is when a validation error occurs, and focus needs to move to the control that is bound to the property in error. This makes it easier for the user to immediately fix the validation problem.
A while ago, Dr. WPF shared a solution to the WPF Disciples that involves hijacking the VM’s IDataErrorInfo implementation and doing some hacky magic that results in focus being sent to the correct control. While a brilliant solution, I preferred finding a more formal, less hacky solution. This blog post presents the implementation that I’ve thrown together, with help from the WPF Disciples over the past few days.
In a ViewModel object, you must implement my IFocusMover interface.
public event EventHandler MoveFocus;
void RaiseMoveFocus(string focusedProperty)
{
var handler = this.MoveFocus;
if (handler != null)
{
var args = new MoveFocusEventArgs(focusedProperty);
handler(this, args);
}
}
The MoveFocus event should be raised when the VM object determines that input focus needs to be sent to the control bound to the ‘focused property.’ For example, if the FirstName property of an object is deemed invalid, you would call the RaiseMoveFocus method, passing “FirstName” as the focused property argument. In the demo application, this results in the TextBox whose Text is bound to the FirstName property to get input focus.
Now let’s shift our attention to the View to see how a control is configured to be able to receive focus. The only thing you must do is use a custom Binding object that I made, called FocusBinding. That class relies on Philipp Sumi’s BindingDecoratorBase class, which allows you to create a custom Binding that can override the all-important ProvideValue method (inherited from MarkupExtension).
public override object ProvideValue(IServiceProvider provider)
{
DependencyObject elem;
DependencyProperty prop;
if (base.TryGetTargetItems(provider, out elem, out prop))
{ FocusController.SetFocusableProperty(elem, prop); }
return base.ProvideValue(provider);
}
You use the FocusBinding in XAML like this:
<TextBox
Text=”{jas:FocusBinding Path=FirstName, ValidatesOnDataErrors=True}”
/>
The ValidatesOnDataErrors property setting is not required, but is used in the demo app to enable support for validation via the VM’s IDataErrorInfo implementation. All controls bound to VM properties that can be “focusable” use the FocusBinding, instead of a normal Binding. When the VM raises its MoveFocus event, the control whose FocusBinding’s Path references the ‘focused property’ will be given input focus.
You can download the source code here. NOTE: Rename the file extension from .DOC to .ZIP and then decompress it. Feedback is welcome!
Every once in a while I post a recording of myself playing a piano piece that I’ve been practicing. This time I’m performing the Allegro from Handel‘s second keyboard suite. The recording quality is not ideal, since I never invested in real recording equipment and software. For those of you who like Baroque keyboard music, I hope you enjoy it!
A few days ago I received a comment from someone named Joe on my blog. He was expressing concern over several aspects of my book Advanced MVVM, including the fact that it is written about a relatively simple game, not something more complicated. After Joe read the book his apprehensions about it disappeared, and he kindly left me this comment:
Josh,
Ok, after reading your book, I have to say “Wow!” Not only have you managed to help me understand some of the frustrations I had with MVVM development, but your book also made some good points (which I shared with my development manager) and reinforced with real examples of issues I faced working on a project using that pattern.
I was very (pleasantly) surprised reading your take on the code-behind vs. NO code-behind mentality. I myself prefer the middle ground, but for some time was forced to do the latter. Yes, it did create several layers of very difficult to follow, understand and maintain code; from your notes and my examples, I was able to reach a compromise on how we should utilize ‘code-behind’.
Now, an interesting story –our architect chose the MVVM pattern after reading your article in MSDN in 2009. However, they chose to enforce “no code-behind” at all for the sake of testability.
The book is awesome; if you can mix MVVM with Prism and come up with a nice 300+ page book with some nice distilled information like that, I’d a) like to help write it; and b) shell out at least $50.00.
Cheers!
Joe
P.S. you’re right, there is no “Silver Bullet”; however, it would be nice to have some guide or set of documentation as to what works well when and where, especially when certain design patterns are applied to solve a problem.
It sounds like Advanced MVVM has another happy customer! 🙂
I’m thrilled to announce that Tim Heuer, one of the top Silverlight community members, evangelists, and Program Managers at Microsoft, has published a review of my book Advanced MVVM. He gave the book a very solid thumbs-up, which made my day! If you’re interested in reading what Tim had to say, here’s the link: http://timheuer.com/blog/archive/2010/03/04/advanced-mvvm-book-for-silverlight-wpf.aspx
Thanks Tim!