In WPF we can set a control focus through code behind as easily as in windows forms.But if you try it using WPF and MVVM it's little bit dificult.We have to write a Dependency Property to handle this issue.
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
namespace ViewModels.ExternalEvents
{
public class SetControlFocus
{
public static readonly DependencyProperty SetFocusProperty = DependencyProperty.RegisterAttached("SetFocus",
typeof(Boolean),
typeof(SetControlFocus),
new PropertyMetadata(OnSetFocusChanged));
private static void OnSetFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d != null && d is Control)
{
if ((bool)e.NewValue)
{
(d as Control).GotFocus += OnLostFocus;
(d as Control).Focus();
}
else
{
(d as Control).GotFocus -= OnLostFocus;
}
}
}
private static void OnLostFocus(object sender, RoutedEventArgs e)
{
if (sender != null && sender is Control)
{
(sender as Control).SetValue(SetFocusProperty, false);
}
}
public static Boolean GetSetFocus(DependencyObject target)
{
return (Boolean)target.GetValue(SetFocusProperty);
}
public static void SetSetFocus(DependencyObject target, Boolean value)
{
target.SetValue(SetFocusProperty, value);
}
}
}
The above code was written in a separate SetControlFocus.cs file in ViewModel.SetFocusProperty is my dependency property name ,remember that what ever name your giving in DependencyProperty.RegisterAttached's first parameter, here my one is "SetFocus",append the "Property"
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
namespace ViewModels.ExternalEvents
{
public class SetControlFocus
{
public static readonly DependencyProperty SetFocusProperty = DependencyProperty.RegisterAttached("SetFocus",
typeof(Boolean),
typeof(SetControlFocus),
new PropertyMetadata(OnSetFocusChanged));
private static void OnSetFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d != null && d is Control)
{
if ((bool)e.NewValue)
{
(d as Control).GotFocus += OnLostFocus;
(d as Control).Focus();
}
else
{
(d as Control).GotFocus -= OnLostFocus;
}
}
}
private static void OnLostFocus(object sender, RoutedEventArgs e)
{
if (sender != null && sender is Control)
{
(sender as Control).SetValue(SetFocusProperty, false);
}
}
public static Boolean GetSetFocus(DependencyObject target)
{
return (Boolean)target.GetValue(SetFocusProperty);
}
public static void SetSetFocus(DependencyObject target, Boolean value)
{
target.SetValue(SetFocusProperty, value);
}
}
}
The above code was written in a separate SetControlFocus.cs file in ViewModel.SetFocusProperty is my dependency property name ,remember that what ever name your giving in DependencyProperty.RegisterAttached's first parameter, here my one is "SetFocus",append the "Property"
string to that name and give as your Dependency property variable name like(Hints in red color.)
public static readonly DependencyProperty SetFocusProperty = DependencyProperty.RegisterAttached("SetFocus",
typeof(Boolean),
typeof(SetControlFocus),
new PropertyMetadata(OnSetFocusChanged));
Any property will associate with a Get and Set methods.Here also we have to use Get and Set methods following with the property name in my case it is GetSetFocus and SetSetFocus.
The second property of the RegisterAttached is the return type of this class.My one is Boolean because, if you go and check the view design page take any control type Focusable= it will show you the values it can accept , i too trying to set true or false from code ,if i send true to this property it will focus / false not focus.
The next parameter is give the name of the class in which your writing the Dependency property.
Then give the event address where your handling the event.
In my event handler i am checking whether the dependency object is control or not if yes then am adding the GotFocu event and my event handler is OnLostFocus here i am setting whatever the value sent by using binding.Here i am using SetValue to set the value it will call SetSetFocus internally.
View:
first add the assembly to the mainwindow where your going to use this .
xmlns:ExternEvents="clr-namespace:ViewModels.ExternalEvents;assembly=ViewModels.STDVERViewModel"
<TextBox Name="txtSearchOrderKey" TabIndex="4" Text="{Binding SearchOrderKey,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" ExternEvents:SetControlFocus.SetFocus="{Binding FocusSearchOrderKeyTxt,Mode=TwoWay}"
Then set the to the control as shown in the red color."FocusSearchOrderKeyTxt" is my Boolean property declared in my viewmodel class.
Like this you can achieve set control focus in WPF with MVVM code .
Comment it..............
public static readonly DependencyProperty SetFocusProperty = DependencyProperty.RegisterAttached("SetFocus",
typeof(Boolean),
typeof(SetControlFocus),
new PropertyMetadata(OnSetFocusChanged));
Any property will associate with a Get and Set methods.Here also we have to use Get and Set methods following with the property name in my case it is GetSetFocus and SetSetFocus.
The second property of the RegisterAttached is the return type of this class.My one is Boolean because, if you go and check the view design page take any control type Focusable= it will show you the values it can accept , i too trying to set true or false from code ,if i send true to this property it will focus / false not focus.
The next parameter is give the name of the class in which your writing the Dependency property.
Then give the event address where your handling the event.
In my event handler i am checking whether the dependency object is control or not if yes then am adding the GotFocu event and my event handler is OnLostFocus here i am setting whatever the value sent by using binding.Here i am using SetValue to set the value it will call SetSetFocus internally.
View:
first add the assembly to the mainwindow where your going to use this .
xmlns:ExternEvents="clr-namespace:ViewModels.ExternalEvents;assembly=ViewModels.STDVERViewModel"
<TextBox Name="txtSearchOrderKey" TabIndex="4" Text="{Binding SearchOrderKey,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" ExternEvents:SetControlFocus.SetFocus="{Binding FocusSearchOrderKeyTxt,Mode=TwoWay}"
Height="21" Width="128" Margin="5 0 0 0"
IsEnabled="{Binding IsEnableSearchOrderKeyTxt}"
ExternEvents:KeyPressEvent.KeyPress="TextBox.Text"
>
Like this you can achieve set control focus in WPF with MVVM code .
Comment it..............