java keypressed tab_在WPF中转到Enter keypress上的下一个控件

回答(7)

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

Jay的答案很好,如果你只想让它适用于几个文本框,但如果你希望你的整个应用程序以这种方式工作,我绝对赞成makwana.a的答案 . 这是我对makwana.a在C#中使用的答案的修改 . 如果活动控件是一个复选框,我还支持通过输入继续下一个控件 .

另请注意,我不使用tag属性来表示焦点是否应继续,而是使用文本框的AcceptsReturn属性,因为它默认为false,您只需在所需的文本框中将其设置为true用作多行,即不应将焦点移到Enter键上 .

在OnStartup void App.xaml中声明这些事件处理程序

EventManager.RegisterClassHandler(typeof(TextBox), TextBox.KeyDownEvent, new KeyEventHandler(TextBox_KeyDown));

EventManager.RegisterClassHandler(typeof(CheckBox), CheckBox.KeyDownEvent, new KeyEventHandler(CheckBox_KeyDown));

以下是使其适用于应用程序所需的其他方法 .

void TextBox_KeyDown(object sender, KeyEventArgs e)

{

if (e.Key == Key.Enter & (sender as TextBox).AcceptsReturn == false) MoveToNextUIElement(e);

}

void CheckBox_KeyDown(object sender, KeyEventArgs e)

{

MoveToNextUIElement(e);

//Sucessfully moved on and marked key as handled.

//Toggle check box since the key was handled and

//the checkbox will never receive it.

if (e.Handled == true)

{

CheckBox cb = (CheckBox)sender;

cb.IsChecked = !cb.IsChecked;

}

}

void MoveToNextUIElement(KeyEventArgs e)

{

// Creating a FocusNavigationDirection object and setting it to a

// local field that contains the direction selected.

FocusNavigationDirection focusDirection = FocusNavigationDirection.Next;

// MoveFocus takes a TraveralReqest as its argument.

TraversalRequest request = new TraversalRequest(focusDirection);

// Gets the element with keyboard focus.

UIElement elementWithFocus = Keyboard.FocusedElement as UIElement;

// Change keyboard focus.

if (elementWithFocus != null)

{

if (elementWithFocus.MoveFocus(request)) e.Handled = true;

}

}

Edit

我更新了代码,以便在移动成功时将按键标记为已处理,并且还会切换复选框,因为密钥已处理并且将不再到达 .

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

以下是我用过的附属物 .

一,示例用法:

Text="{Binding Name, Mode=TwoWay}"

UI:FocusAdvancement.AdvancesByEnterKey="True" />

(UI是我定义以下内容的命名空间别名 . )

附属物:

public static class FocusAdvancement

{

public static bool GetAdvancesByEnterKey(DependencyObject obj)

{

return (bool)obj.GetValue(AdvancesByEnterKeyProperty);

}

public static void SetAdvancesByEnterKey(DependencyObject obj, bool value)

{

obj.SetValue(AdvancesByEnterKeyProperty, value);

}

public static readonly DependencyProperty AdvancesByEnterKeyProperty =

DependencyProperty.RegisterAttached("AdvancesByEnterKey", typeof(bool), typeof(FocusAdvancement),

new UIPropertyMetadata(OnAdvancesByEnterKeyPropertyChanged));

static void OnAdvancesByEnterKeyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

{

var element = d as UIElement;

if(element == null) return;

if ((bool)e.NewValue) element.KeyDown += Keydown;

else element.KeyDown -= Keydown;

}

static void Keydown(object sender, KeyEventArgs e)

{

if(!e.Key.Equals(Key.Enter)) return;

var element = sender as UIElement;

if(element != null) element.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));

}

}

你还说"instead of tab,"所以我建议反对它,因为它是一个常见的,众所周知的范例,但如果是这种情况,你可以在附加属性中添加 PreviewKeyDown 处理程序,检查tab键,并设置 Handled = true 为事件args .

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

示例解决方案:在堆栈面板中使用PreviewKeyDown . 预览...是一个泡沫,因此可以在更高级别处理事件 . 对于不同的元素类型,您可能需要以不同的方式处理它,例如按钮似乎应该保持回车键而不是将注意力更改为回车键 .

这是xaml:

Hello

World

test

以下是代码背后的代码:

private void StackPanel_PreviewKeyDown(object sender, KeyEventArgs e)

{

if (e.Key == Key.Enter)

{

TextBox s = e.Source as TextBox;

if (s != null)

{

s.MoveFocus(new TraversalRequest( FocusNavigationDirection.Next));

}

e.Handled = true;

}

}

这只是一个用于概念验证的沙箱 .

快乐编码......

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

将此代码写入应用程序文件的onstartup事件中

EventManager.RegisterClassHandler(GetType(TextBox), TextBox.KeyDownEvent, New RoutedEventHandler(AddressOf TextBox_KeyDown))

然后将TextBox_KeyDown sub定义为

Private Sub TextBox_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Input.KeyEventArgs)

If e.Key = Key.Enter And TryCast(sender, TextBox).Tag <> "1" Then

' Creating a FocusNavigationDirection object and setting it to a

' local field that contains the direction selected.

Dim focusDirection As FocusNavigationDirection = FocusNavigationDirection.Next

' MoveFocus takes a TraveralReqest as its argument.

Dim request As New TraversalRequest(focusDirection)

' Gets the element with keyboard focus.

Dim elementWithFocus As UIElement = TryCast(Keyboard.FocusedElement, UIElement)

' Change keyboard focus.

If elementWithFocus IsNot Nothing Then

elementWithFocus.MoveFocus(request)

End If

End If

End Sub

我使用了文本框的“tag”属性来跳过移动焦点 . 即如果有一段时间你不想在按下输入键的情况下移动到下一个控件(在多行文本框的情况下需要输入以创建新行) . 只需将tag属性设置为1即可 .

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

public class EnterKeyTraversal

{

public static bool GetIsEnabled(DependencyObject obj)

{

return (bool)obj.GetValue(IsEnabledProperty);

}

public static void SetIsEnabled(DependencyObject obj, bool value)

{

obj.SetValue(IsEnabledProperty, value);

}

static void ue_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)

{

var ue = e.OriginalSource as FrameworkElement;

if (e.Key == Key.Enter)

{

e.Handled = true;

ue.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));

}

}

private static void ue_Unloaded(object sender, RoutedEventArgs e)

{

var ue = sender as FrameworkElement;

if (ue == null) return;

ue.Unloaded -= ue_Unloaded;

ue.PreviewKeyDown -= ue_PreviewKeyDown;

}

public static readonly DependencyProperty IsEnabledProperty =

DependencyProperty.RegisterAttached("IsEnabled", typeof(bool),

typeof(EnterKeyTraversal), new UIPropertyMetadata(false, IsEnabledChanged));

static void IsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

{

var ue = d as FrameworkElement;

if (ue == null) return;

if ((bool)e.NewValue)

{

ue.Unloaded += ue_Unloaded;

ue.PreviewKeyDown += ue_PreviewKeyDown;

}

else

{

ue.PreviewKeyDown -= ue_PreviewKeyDown;

}

}

}

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

首先发生的事件是向 PreviewKeyDown 触发时将调用的每个元素添加触发器 . 还要添加Dependency属性并绑定 FrameworkElement ,您不会将焦点放在 . 在触发器内提供绑定元素的设置 Focus .

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

使用代码隐藏:

我想出了下面的代码 . 请注意,它没有设置e.Handled . 此外,MoveFocus_Next不会返回移动焦点是否成功,而是返回参数是否为空 . 您可以根据需要添加或删除要处理的控件类型 . 代码是为应用程序的MainWindow编写的,但也处理其他窗口 . 您还可以从App_Startup事件调整代码以进行调用 .

using System.Windows;

using System.Windows.Controls;

using System.Windows.Input;

public partial class MainWindow : Window

{

private bool MoveFocus_Next(UIElement uiElement)

{

if (uiElement != null)

{

uiElement.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));

return true;

}

return false;

}

public MainWindow()

{

InitializeComponent();

}

private void Window_Loaded(object sender, RoutedEventArgs e)

{

EventManager.RegisterClassHandler(typeof(Window), Window.PreviewKeyUpEvent, new KeyEventHandler(Window_PreviewKeyUp));

}

private void Window_PreviewKeyUp(object sender, KeyEventArgs e)

{

if (e.Key == Key.Enter)

{

IInputElement inputElement = Keyboard.FocusedElement;

if (inputElement != null)

{

System.Windows.Controls.Primitives.TextBoxBase textBoxBase = inputElement as System.Windows.Controls.Primitives.TextBoxBase;

if (textBoxBase != null)

{

if (!textBoxBase.AcceptsReturn)

MoveFocus_Next(textBoxBase);

return;

}

if (

MoveFocus_Next(inputElement as ComboBox)

||

MoveFocus_Next(inputElement as Button)

||

MoveFocus_Next(inputElement as DatePicker)

||

MoveFocus_Next(inputElement as CheckBox)

||

MoveFocus_Next(inputElement as DataGrid)

||

MoveFocus_Next(inputElement as TabItem)

||

MoveFocus_Next(inputElement as RadioButton)

||

MoveFocus_Next(inputElement as ListBox)

||

MoveFocus_Next(inputElement as ListView)

||

MoveFocus_Next(inputElement as PasswordBox)

||

MoveFocus_Next(inputElement as Window)

||

MoveFocus_Next(inputElement as Page)

||

MoveFocus_Next(inputElement as Frame)

)

return;

}

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值