So how to Focus an TextBox on Button click using the MVVM Pattern?
i created an simple Testproject Based on this Answer which works on the first click, but after tha
Your attached property value is never going back to false after the initial default is overwritten. hence your FocusExtension
class is not calling Focus()
on the TextBox
since the PropertyChanged
does not need to fire when setting IsFocused
in your VM to true.
switch the OnIsFocusedPropertyChanged(...)
from:
private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var uie = (UIElement)d;
if ((bool)e.NewValue)
uie.Focus(); // Don't care about false values.
}
to
private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
var uie = (UIElement)d;
if (!((bool)e.NewValue))
return;
uie.Focus();
uie.LostFocus += UieOnLostFocus;
}
private static void UieOnLostFocus(object sender, RoutedEventArgs routedEventArgs) {
var uie = sender as UIElement;
if (uie == null)
return;
uie.LostFocus -= UieOnLostFocus;
uie.SetValue(IsFocusedProperty, false);
}
Update:
Along with the above change also make sure
local:FocusExtension.IsFocused="{Binding IsFocused}"
is switched to
local:FocusExtension.IsFocused="{Binding IsFocused, Mode=TwoWay}"
Working Download Link
Another Update
To set the Mode=TwoWay
as default for this attached property in FocusExtension
class switch
public static readonly DependencyProperty IsFocusedProperty = DependencyProperty.RegisterAttached(
"IsFocused",
typeof(bool),
typeof(FocusExtension),
new UIPropertyMetadata(
false,
OnIsFocusedPropertyChanged));
to
public static readonly DependencyProperty IsFocusedProperty = DependencyProperty.RegisterAttached(
"IsFocused",
typeof(bool),
typeof(FocusExtension),
new FrameworkPropertyMetadata(
false,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
OnIsFocusedPropertyChanged));
You can skip explicitly specifying Mode=TwoWay
in xaml with the above declaration.
You should make a command for lostFocus event, and when focus is lost, set isFocused property to false, then it will be working. Add Interactivity and Interactions librarys into your project, than you will be able to write something like :
<i:Interaction.Triggers>
<i:EventTrigger EventName="LostFocus">
<ei:CallMethodAction TargetObject="{Binding}" MethodName="OnLostFocus"/>
</i:EventTrigger>
</i:Interaction.Triggers>
and in your viewModel write:
public void OnLostFocus()
{IsFocused = false;}
and move RaisePropertyChanged to the setter of your property
I got the same issue before. I did a trick. In your OnClick method, do something like this:
if(IsFocus == true)
IsFocus = false;
IsFocus = true;