我有一个WPF ComboBox
,其IsEditable
属性绑定到视图模型,可以打开和关闭它。当它打开时,我想将焦点放在ComboBox
并选择编辑TextBox
中的所有文字。
我看不到最好的结果。我应该替换ControlTemplate
,继承ComboBox
基类,并提供所需的属性,使用附加属性还是其他方法?
答案 0 :(得分:6)
我有一个解决方案。
我正在使用模型 - 视图 - 视图模型和附加属性方法的组合。
首先,您需要了解MVVM中的消息传递系统才能实现此功能,并了解您的命令。因此,从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
此代码显示的是当我们将附加属性 SelectWhenFocused设置为true 时,它将注册以侦听 GotFocused事件并选择其中的所有文本。
使用很简单:
<ComboBox
IsEditable="True"
ComboBoxHelper:EditableComboBox.SelectWhenFocused="True"
x:Name="EditBox" />
现在我们需要一个按钮,在单击时将焦点设置在ComboBox上。
<Button
Command="{Binding Focus}"
CommandParameter="{Binding ElementName=EditBox}"
Grid.Column="1" >Focus</Button>
注意 CommandParameter 如何通过名称EditBox绑定到ComboBox。当命令执行时,只有这个ComboBox被聚焦并且所有文本都被选中。
在我的ViewModel中,我将 Focus命令声明如下:
public SimpleCommand Focus { get; set; }
public WindowVM()
{
Focus = new SimpleCommand {ExecuteDelegate = x => Broadcast(x as ComboBox)};
}
这是经过测试和验证的技术,对我有用。我希望这对你的问题不是一个过度的解决方案。祝你好运。