WPF:选择所有文本并将焦点设置到组合框的可编辑文本框 [英] WPF: Selecting all the text in and setting focus to a ComboBox's editable textbox

查看:17
本文介绍了WPF:选择所有文本并将焦点设置到组合框的可编辑文本框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我看不出最好的办法来完成这件事.我应该替换 ControlTemplate,子类化 ComboBox 基类,并提供所需的属性、使用附加属性或其他方法吗?

解决方案

我有一个解决方案.

我结合使用了模型-视图-视图模型和附加属性方法.

首先,您需要了解 MVVM 中的消息系统以使其正常工作,并了解您的命令.因此,从附加属性开始,我们开始将 IsFocused 事件设置为我们希望聚焦并选择所有文本的组合框.

 #region 选择焦点public static bool GetSelectWhenFocused(DependencyObject obj){返回(布尔)obj.GetValue(SelectWhenFocusedProperty);}公共静态无效 SetSelectWhenFocused(DependencyObject obj,布尔值){obj.SetValue(SelectWhenFocusedProperty, value);}//使用 DependencyProperty 作为 SelectWhenFocused 的后备存储.这可以启用动画、样式、绑定等...公共静态只读 DependencyProperty SelectWhenFocusedProperty =DependencyProperty.RegisterAttached("SelectWhenFocused", typeof(bool), typeof(EditableComboBox), new UIPropertyMetadata(OnSelectOnFocusedChanged));公共静态无效 OnSelectOnFocusedChanged(DependencyObject obj,DependencyPropertyChangedEventArgs args){bool SetProperty = (bool)args.NewValue;var comboBox = obj as ComboBox;if (comboBox == null) 返回;如果(设置属性){组合框.GotFocus += GotFocused;Messenger.Default.Register(comboBox, Focus);}别的{comboBox.GotFocus -= GotFocused;Messenger.Default.Unregister(comboBox, Focus);}}public static void GotFocused(对象发送者,RoutedEventArgs e){var comboBox = 发送者为 ComboBox;if(comboBox == null) 返回;var textBox = comboBox.FindChild(typeof(TextBox), "PART_EditableTextBox") as TextBox;if (textBox == null) 返回;textBox.SelectAll();}公共静态无效焦点(组合框组合框){if(comboBox == null) 返回;组合框.焦点();}#endregion

这段代码显示的是,当我们将附加属性 SelectWhenFocused 设置为 true 时,它将注册以侦听 GotFocused 事件 并选择其中的所有文本.>

使用很简单:

现在我们需要一个按钮,当点击时将焦点设置在组合框上.

<按钮命令="{绑定焦点}"CommandParameter="{Binding ElementName=EditBox}"Grid.Column="1" >焦点</按钮>

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

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

public SimpleCommand Focus { get;放;}公共 WindowVM(){Focus = new SimpleCommand {ExecuteDelegate = x =>广播(x 作为组合框)};}

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

I have a WPF ComboBox which has its IsEditable property bound to a view model which can switch it on and off. When it is switched on, I want to give focus to the ComboBox and select all the text in the edit TextBox.

I can't see the best to accomplish this. Should I replace the ControlTemplate, subclass the ComboBox base class, and provide the needed properties, use Attached Properties, or some other approach?

解决方案

I have a solution for you.

I'm using a combination of Model-View-ViewModel and Attached Property approach.

Firstly, you need to know the Messaging system in MVVM for this to work, as well as know your Commands. So starting with Attached Properties, we begin to set an IsFocused event to the combo box we would like to have focused and all text selected.

  #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

What this code shows is when we set the Attached Property SelectWhenFocused to true, it will register to listen for the GotFocused Event and select all the text inside.

To use is simple:

<ComboBox
  IsEditable="True"
  ComboBoxHelper:EditableComboBox.SelectWhenFocused="True"
  x:Name="EditBox" />

Now we need a button that will set the focus on the ComboBox when clicked on.

<Button
  Command="{Binding Focus}"
  CommandParameter="{Binding ElementName=EditBox}"
  Grid.Column="1" >Focus</Button>

Notice how the CommandParameter is binding to the ComboBox by its name EditBox. This is so when the command executes, only this ComboBox gets focused and all text selected.

In my ViewModel, I have the Focus command declared as following:

public SimpleCommand Focus { get; set; }
public WindowVM()
{
  Focus = new SimpleCommand {ExecuteDelegate = x => Broadcast(x as ComboBox)};
}

This is a tested and proven technique that works for me. I hope it's not an overkill solution to your problem. Good luck.

这篇关于WPF:选择所有文本并将焦点设置到组合框的可编辑文本框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆