在WPF中从ViewModel设置焦点TextBox

时间:2013-10-01 13:24:41

标签: wpf xaml mvvm wpf-controls

我有一个主窗口,其中有足够的用户控制。并使用导航我能够访问用户控件。但问题是如何在打开用户控件时将焦点设置在第一个文本框上。

我尝试使用依赖属性和布尔标志,我能够成功一点。当我第一次渲染UserControl时,我能够聚焦,但是当我第二次打开时,我无法将焦点设置在TextBox上。

还有一件事,我已经验证了TextBoxes,如果验证失败,那么文本框应该被清空,焦点应该放在相应的文本框上。

如何在WPF(CLR 3.5,VS2008)中使用MVVM实现这一目标

提前感谢。

3 个答案:

答案 0 :(得分:1)

如果你有UserControl,那么你也有CodeBehind。

将它放在你的代码隐藏中,你就可以了。

this.Loaded += (o, e) => { Keyboard.Focus(textBox1) }

如果您希望收听验证错误,请将其放在UserControl XAML中。

<UserControl>
 <Grid Validation.Error="OnValidationError">
  <TextBox Text{Binding ..., NotifyOnValidationError=true } />
 </Grid>
<UserControl>

在UserControl的CodeBehind中,您将拥有以下内容:

public void OnValidationError(o , args)
{
  if(o is TextBox)
  {
    (TextBox)o).Text = string.Empty;
  }
}

答案 1 :(得分:0)

您应该使用AttachedProperty坚持MVVM模式,它将使您的视图模型独立于UI代码并完全可单元测试。以下附加属性绑定布尔属性以聚焦并突出显示TextBox,如果您不想突出显示,则可以删除突出显示代码并使用焦点代码。

public class TextBoxBehaviors
    {
        #region HighlightTextOnFocus Property

        public static readonly DependencyProperty HighlightTextOnFocusProperty =
            DependencyProperty.RegisterAttached("HighlightTextOnFocus", typeof (bool), typeof (TextBoxBehaviors),
                                                new PropertyMetadata(false, HighlightTextOnFocusPropertyChanged));

        public static bool GetHighlightTextOnFocus(DependencyObject obj)
        {
            return (bool) obj.GetValue(HighlightTextOnFocusProperty);
        }

        public static void SetHighlightTextOnFocus(DependencyObject obj, bool value)
        {
            obj.SetValue(HighlightTextOnFocusProperty, value);
        }

        private static void HighlightTextOnFocusPropertyChanged(DependencyObject sender,
                                                                DependencyPropertyChangedEventArgs e)
        {
            var uie = sender as UIElement;
            if (uie == null) return;

            if ((bool) e.NewValue)
            {
                uie.GotKeyboardFocus += OnKeyboardFocusSelectText;
                uie.PreviewMouseLeftButtonDown += OnMouseLeftButtonDownSetFocus;
            }
            else
            {
                uie.GotKeyboardFocus -= OnKeyboardFocusSelectText;
                uie.PreviewMouseLeftButtonDown -= OnMouseLeftButtonDownSetFocus;
            }
        }

        private static void OnKeyboardFocusSelectText(object sender, KeyboardFocusChangedEventArgs e)
        {
            var textBox = sender as TextBox;
            if (textBox == null) return;

            textBox.SelectAll();
        }

        private static void OnMouseLeftButtonDownSetFocus(object sender, MouseButtonEventArgs e)
        {
            var textBox = sender as TextBox;
            if (textBox == null) return;

            if (!textBox.IsKeyboardFocusWithin)
            {
                textBox.Focus();
                e.Handled = true;
            }
        }

        #endregion
    }

您可以在TextBox上使用此附加属性,您想要聚焦/突出显示...

<TextBox ... local:TextBoxBehaviors.HighlightTextOnFocus="{Binding IsScrolledToEnd}" ... />

答案 2 :(得分:0)

您也可以尝试使用FocusManager

<UserControl>
 <Grid FocusManager.FocusedElement="{Binding Path=FocusedTextBox, ElementName=UserControlName}">
  <TextBox x:Name="FocusedTextBox" />
 </Grid>
<UserControl>