WPF:选择所有文本并将焦点设置为ComboBox的可编辑文本框

cod*_*zen 3 wpf combobox focus

我有一个WPF ComboBox,其IsEditable属性绑定到一个视图模型,可以打开和关闭它.当它打开时,我想给焦点ComboBox并选择编辑中的所有文本TextBox.

我无法看到最好的成就.我应该替换基类的ControlTemplateComboBox类,并提供所需的属性,使用附加属性还是其他方法?

Tri*_*ran 6

我有一个解决方案给你.

我正在使用Model-View-ViewModel和Attached Property方法的组合.

首先,您需要了解MVVM中的Messaging系统才能使用它,以及了解您的命令.因此,从Attached Properties开始,我们开始将IsFocused事件设置到我们想要聚焦的组合框并选择所有文本.

  #region Select On Focus

  public static bool GetSelectWhenFocused(DependencyObject obj)
  {
    return (bool)obj.GetValue(SelectWhenFocusedProperty);
  }

  public static void SetSelectWhenFocused(DependencyObject obj, bool value)
  {
    obj.SetValue(SelectWhenFocusedProperty, value);
  }

  // Using a DependencyProperty as the backing store for SelectWhenFocused.  This enables animation, styling, binding, etc...
  public static read-only DependencyProperty SelectWhenFocusedProperty =
      DependencyProperty.RegisterAttached("SelectWhenFocused", typeof(bool), typeof(EditableComboBox), new UIPropertyMetadata(OnSelectOnFocusedChanged));

  public static void OnSelectOnFocusedChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
  {
    bool SetProperty = (bool)args.NewValue;     

    var comboBox = obj as ComboBox;
    if (comboBox == null) return;

    if (SetProperty)
    {
      comboBox.GotFocus += GotFocused;
      Messenger.Default.Register<ComboBox>(comboBox, Focus);
    }
    else
    {
      comboBox.GotFocus -= GotFocused;
      Messenger.Default.Unregister<ComboBox>(comboBox, Focus);
    }
  }

  public static void GotFocused(object sender, RoutedEventArgs e)
  {
    var comboBox = sender as ComboBox;
    if(comboBox == null) return;

    var textBox = comboBox.FindChild(typeof(TextBox), "PART_EditableTextBox") as TextBox;
    if (textBox == null) return;

    textBox.SelectAll();
  }

  public static void Focus(ComboBox comboBox)
  {
    if(comboBox == null) return;
    comboBox.Focus();
  }
  #endregion
Run Code Online (Sandbox Code Playgroud)

这段代码显示的是当我们将Attached Property SelectWhenFocused设置为true时,它将注册以侦听GotFocused事件并选择里面的所有文本.

使用很简单:

<ComboBox
  IsEditable="True"
  ComboBoxHelper:EditableComboBox.SelectWhenFocused="True"
  x:Name="EditBox" />
Run Code Online (Sandbox Code Playgroud)

现在我们需要一个按钮,在单击时将焦点设置在ComboBox上.

<Button
  Command="{Binding Focus}"
  CommandParameter="{Binding ElementName=EditBox}"
  Grid.Column="1" >Focus</Button>
Run Code Online (Sandbox Code Playgroud)

注意CommandParameter如何通过名称EditBox绑定到ComboBox.当命令执行时,只有这个ComboBox被聚焦并且所有文本被选中.

在我的ViewModel中,我将Focus命令声明如下:

public SimpleCommand Focus { get; set; }
public WindowVM()
{
  Focus = new SimpleCommand {ExecuteDelegate = x => Broadcast(x as ComboBox)};
}
Run Code Online (Sandbox Code Playgroud)

这是一种经过测试和验证的技术,对我有用.我希望这对你的问题不是一个过度的解决方案.祝好运.