9

I am validating user input in my viewmodel and throwing validation message in case validation fails for any of values.

I just need to set the focus to the particular control for which validation has failed.

Any idea how to achieve this ?

Sheridan
  • 68,826
  • 24
  • 143
  • 183
user2519971
  • 345
  • 3
  • 12
  • 27
  • Concept: Make an AttachedBehavior or a Custom Control - have a new dependency property which when set to true you focus that control and set it back to false, so you're ready for the next time it is set to true. – bland Oct 29 '13 at 12:21
  • 1
    For user input, the control already has focus, right? For programmatical changes of control values, how do you ensure that only one control fails validation? If multiple controls would fail validation, which would be the chosen one to get the focus? –  Oct 29 '13 at 12:21
  • A better implementation of this question could be found here: https://stackoverflow.com/a/7972361/9758687 – Coden Jul 24 '18 at 11:22

1 Answers1

13

Generally, when we want to use a UI event while adhering to the MVVM methodology, we create an Attached Property:

public static DependencyProperty IsFocusedProperty = DependencyProperty.RegisterAttached("IsFocused", typeof(bool), typeof(TextBoxProperties), new UIPropertyMetadata(false, OnIsFocusedChanged));

public static bool GetIsFocused(DependencyObject dependencyObject)
{
    return (bool)dependencyObject.GetValue(IsFocusedProperty);
}

public static void SetIsFocused(DependencyObject dependencyObject, bool value)
{
    dependencyObject.SetValue(IsFocusedProperty, value);
}

public static void OnIsFocusedChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
    TextBox textBox = dependencyObject as TextBox;
    bool newValue = (bool)dependencyPropertyChangedEventArgs.NewValue;
    bool oldValue = (bool)dependencyPropertyChangedEventArgs.OldValue;
    if (newValue && !oldValue && !textBox.IsFocused) textBox.Focus();
}

This property is used like this:

<TextBox Attached:TextBoxProperties.IsFocused="{Binding IsFocused}" ... />

Then we can focus the TextBox from the view model by changing the IsFocused property to true:

IsFocused = false; // You may need to set it to false first if it is already true
IsFocused = true;
Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • 2
    @Sheridan: how you are referring typeof(TextBoxProperties)? I mean what namespace required to access this – user2519971 Oct 29 '13 at 13:50
  • For a full explanation, please read the [Attached Properties Overview](http://msdn.microsoft.com/en-us/library/ms749011.aspx) page on MSDN... for the short explanation, that is the class that I defined that property in. `Attached` is the namespace of that class. That is why the property is accessed like this: `Attached:TextBoxProperties.IsFocused`. – Sheridan Oct 29 '13 at 13:57
  • 1
    You're welcome. If this answer has provided an acceptable solution to your problem, could you please let other users know by [*selecting it as the accepted answer*](http://stackoverflow.com/help/someone-answers), as is customary on this website? – Sheridan Oct 29 '13 at 15:22
  • I get an error stating, "TextBoxProperties is not supported in a WPF project" any idea what I'm doing wrong? – Automate This Mar 13 '17 at 20:59
  • 1
    You need to import the attached property by [defining a XAML namespace](https://learn.microsoft.com/en-us/dotnet/framework/wpf/advanced/xaml-namespaces-and-namespace-mapping-for-wpf-XAML) for it (in the case of this example, the namespace prefix that I used was `Attached`, hence `Attached:TextBoxProperties`). – Sheridan Jun 15 '17 at 15:34
  • I can see a cursor displayed indicating focus, but i have read there is Focus and Keyboard focus - is there anyway we can get KeyBoard focus using the similar technique ? – Jeffrey Holmes Jun 14 '18 at 13:45
  • See my answer to the [Get and restore WPF keyboard focus](https://stackoverflow.com/questions/19289994/get-and-restore-wpf-keyboard-focus/19290706#19290706) question. – Sheridan Jun 15 '18 at 12:26