[英]How to Focus an TextBox on Button click
那么如何使用MVVM模式关注按钮上的TextBox?
我创建了一个简单的测试项目基于这个答案 ,它在第一次点击时起作用,但之后它不再设置焦点。 我错过了什么?
XAML(查看)
<Grid>
<TextBox Height='23' HorizontalAlignment='Left' Margin='12,12,0,0' VerticalAlignment='Top' Width='120'
Text='{Binding TheText}'
local:FocusExtension.IsFocused="{Binding IsFocused}"/>
<Button Content='Click' Height='23' HorizontalAlignment='Left' Margin='138,11,0,0' VerticalAlignment='Top' Width='75'
Command='{Binding ClickCommand}'/>
<Button Content='Just to deFocus' Height='28' HorizontalAlignment='Left' Margin='14,44,0,0' Name='button1' VerticalAlignment='Top' Width='199' />
</Grid>
视图模型
public class ViewModel : INotifyPropertyChanged
{
public string TheText { get; set; }
public bool IsFocused { get; set; }
private RelayCommand _clickCommand;
public ICommand ClickCommand
{
get { return _clickCommand ?? (_clickCommand = new RelayCommand(param => this.OnClick())); }
}
private void OnClick()
{
IsFocused = true;
RaisePropertyChanged("IsFocused");
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
#endregion
}
这是一个下载链接 ,带有准备好的项目(VS2010),适用于懒人;)
在覆盖初始默认值后,您的附加属性值永远不会返回false。 因此,您的FocusExtension
类不会在TextBox
上调用Focus()
,因为在将VM中的IsFocused
设置为true时, PropertyChanged
不需要触发。
切换OnIsFocusedPropertyChanged(...)
从:
private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var uie = (UIElement)d;
if ((bool)e.NewValue)
uie.Focus(); // Don't care about false values.
}
至
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);
}
更新:
随着上述变化也确定
local:FocusExtension.IsFocused="{Binding IsFocused}"
切换到
local:FocusExtension.IsFocused="{Binding IsFocused, Mode=TwoWay}"
另一个更新
在FocusExtension
类开关中将Mode=TwoWay
设置为此附加属性的默认值
public static readonly DependencyProperty IsFocusedProperty = DependencyProperty.RegisterAttached(
"IsFocused",
typeof(bool),
typeof(FocusExtension),
new UIPropertyMetadata(
false,
OnIsFocusedPropertyChanged));
至
public static readonly DependencyProperty IsFocusedProperty = DependencyProperty.RegisterAttached(
"IsFocused",
typeof(bool),
typeof(FocusExtension),
new FrameworkPropertyMetadata(
false,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
OnIsFocusedPropertyChanged));
您可以使用上面的声明跳过在xaml中显式指定Mode=TwoWay
。
您应该为lostFocus事件发出命令,当焦点丢失时,将isFocused属性设置为false,然后它将起作用。 将交互性和交互图书馆添加到您的项目中,而不是您可以编写如下内容:
<i:Interaction.Triggers>
<i:EventTrigger EventName="LostFocus">
<ei:CallMethodAction TargetObject="{Binding}" MethodName="OnLostFocus"/>
</i:EventTrigger>
</i:Interaction.Triggers>
并在您的viewModel中写道:
public void OnLostFocus()
{IsFocused = false;}
并将RaisePropertyChanged移动到您的属性的setter
我以前遇到过同样的问题。 我做了一个技巧。 在OnClick方法中,执行以下操作:
if(IsFocus == true)
IsFocus = false;
IsFocus = true;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.