WPF – 单击按钮时设置焦点 – 无代码

有没有办法使用WPF TriggerFocus从一个控件设置为另一个?

如下例所示:

              

有没有办法让这个EventTrigger专注于textBox“txtName”?

我试图找到使用严格的MVVM做这样的事情的方法。 如果这是不应该通过XAML(在MVVM中)完成的,那么这很好。 但我希望看到一些文档,说明它如何适应在XAML之外的MVVM模式。

您是否考虑过使用附加行为? 它们易于实现并使用AttachedProperty。 虽然它仍然需要代码,但是这个代码在类中被抽象出来并被重用。 它们可以消除“后面的代码”的需要,并且经常与MVVM模式一起使用。

试试这个,看看它是否适合你。

 public class EventFocusAttachment { public static Control GetElementToFocus(Button button) { return (Control)button.GetValue(ElementToFocusProperty); } public static void SetElementToFocus(Button button, Control value) { button.SetValue(ElementToFocusProperty, value); } public static readonly DependencyProperty ElementToFocusProperty = DependencyProperty.RegisterAttached("ElementToFocus", typeof(Control), typeof(EventFocusAttachment), new UIPropertyMetadata(null, ElementToFocusPropertyChanged)); public static void ElementToFocusPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { var button = sender as Button; if (button != null) { button.Click += (s, args) => { Control control = GetElementToFocus(button); if (control != null) { control.Focus(); } }; } } } 

然后在你的XAML做类似……

   

我不在视觉工作室附近所以我现在不能尝试这个,但是在我的头脑中,你应该能够做到这样的事情:

 FocusManager.FocusedElement="{Binding ElementName=txtName}"> 

编辑:

这里有一个关于此的后续问题(最近询问): 如何仅在xaml中设置自动对焦? 其中包含此方法,以及如何使用它的一些不同的想法。

你也可以使用WPF行为……

  public class FocusElementAfterClickBehavior : Behavior { private ButtonBase _AssociatedButton; protected override void OnAttached() { _AssociatedButton = AssociatedObject; _AssociatedButton.Click += AssociatedButtonClick; } protected override void OnDetaching() { _AssociatedButton.Click -= AssociatedButtonClick; } void AssociatedButtonClick(object sender, RoutedEventArgs e) { Keyboard.Focus(FocusElement); } public Control FocusElement { get { return (Control)GetValue(FocusElementProperty); } set { SetValue(FocusElementProperty, value); } } // Using a DependencyProperty as the backing store for FocusElement. This enables animation, styling, binding, etc... public static readonly DependencyProperty FocusElementProperty = DependencyProperty.Register("FocusElement", typeof(Control), typeof(FocusElementAfterClickBehavior), new UIPropertyMetadata()); } 

以下是使用该行为的XAML。

包含名称空间:

 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:local="clr-namespace:WpfApplication1" 

将WPF行为附加到按钮并将要设置焦点的元素绑定到:

   

所以这样你就没有代码了,它可以重用于从ButtonBaseinheritance的任何控件。

希望这有助于某人。

你需要一个TriggerAction来调用所需控件上的Focus()方法。

 public class SetFocusTrigger : TargetedTriggerAction { protected override void Invoke(object parameter) { if (Target == null) return; Target.Focus(); } } 

要将焦点设置为Control,请在LayoutRoot(或任何控件)之后放置一个Triggers集合,选择事件作为触发器,并选择SetFocusTrigger作为要运行的类。 在SetFocusTrigger声明中,您使用TargetName属性放置要接收焦点的控件的名称。

  

这是你想要的吗?

     

C#:

  public void MoveFocusOnClick(object sender, RoutedEventArgs e) { Keyboard.Focus(txtName); // Or your own logic } 

这与Ian Oakes的解决方案相同,但我做了一些小改动。

  1. 按钮类型可以更通用,即ButtonBase ,以处理更多情况,例如ToggleButton
  2. 目标类型也可以更通用,即UIElement 。 从技术上讲,我想这可能是IInputElement
  3. 我将事件处理程序设置为静态,以便每次都不会生成运行时闭包。 为了确保它保持静止,我将它移出了lambda。

非常感谢伊恩。


 public sealed class EventFocusAttachment { [DebuggerStepThrough] public static UIElement GetTarget(ButtonBase b) { return (UIElement)b.GetValue(TargetProperty); } [DebuggerStepThrough] public static void SetTarget(ButtonBase b, UIElement target) { b.SetValue(TargetProperty, target); } public static readonly DependencyProperty TargetProperty = DependencyProperty.RegisterAttached("Target", typeof(UIElement), typeof(EventFocusAttachment), new UIPropertyMetadata(null, TargetPropertyChanged)); public static void TargetPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs _) { ButtonBase bb; if ((bb = o as ButtonBase) != null) bb.Click += handler; } static void handler(Object o, RoutedEventArgs _) { UIElement target; if ((target = GetTarget((ButtonBase)o)) != null) target.Focus(); } }; 

用法与上述基本相同:

  

请注意,事件可以定位/聚焦原始按钮本身。

看看你是否正在使用任何Dispatcher然后它会有所帮助,但这是我在我的代码中使用的一个简短技巧。 只需在XAML中使用Loaded事件并创建一个新的处理程序。 在该处理程序中粘贴此代码和宾果游戏! 你准备好了

你加载的事件有一些参数在这里……

 { Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Normal, new System.Action(() => { The element to be focused goes here...... })); } 

PS:它需要Windows。 如果你不知道线程;)