繁体   English   中英

如何在按钮单击上聚焦TextBox

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM