将焦点放在 WPF 中的自定义(用户)控件上
比如说,我需要使用键盘在表单中移动自定义(用户)控件。
行为很简单:用户单击控件,然后可以使用键盘移动它(向上/d/l/r)。
在此示例中,我将使用 Canvas,而不是 UserControl。
问题是,当我“聚焦”我的控件时,或者在文本框的一系列“步骤”之后我失去了它,或者我根本没有收到它......
XAML:
<Window x:Class="WpfApplication14.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
PreviewKeyDown="Window_PreviewKeyDown">
<Grid>
<TextBox Name="textBox1"
Margin="91,66,292,223" Width="120"
Text="Good morning, miss Hilton!"/>
<Canvas Name="canvas1" Focusable="True"
Margin="124,112,179,99" Width="200"
Background="AliceBlue"
MouseDown="canvas1_MouseDown"
PreviewKeyDown="canvas1_PreviewKeyDown" />
</Grid>
</Window>
CS:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void canvas1_MouseDown(object sender, MouseButtonEventArgs e)
{
Console.WriteLine("canvas_MouseDown 0, canvas1.IsFocused? {0}",
canvas1.IsFocused);
canvas1.Focus();
Console.WriteLine("canvas_MouseDown 1, canvas1.IsFocused? {0}",
canvas1.IsFocused);
}
private void canvas1_PreviewKeyDown(object sender, KeyEventArgs e)
{
Console.WriteLine("canvas_PreviewKeyDown, canvas1.IsFocused? {0}",
canvas1.IsFocused);
if (canvas1.IsFocused)
MoveCanvas(e.Key);
}
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
//Console.WriteLine("Window_PreviewKeyDown, canvas1.IsFocused? {0}",
// canvas1.IsFocused);
//if (canvas1.IsFocused)
// MoveCanvas(e.Key);
}
void MoveCanvas(Key key)
{
int delta = 10;
switch (key)
{
case Key.Left: canvas1.Margin = new Thickness(
canvas1.Margin.Left - delta,
canvas1.Margin.Top,
canvas1.Margin.Right,
canvas1.Margin.Bottom);
break;
case Key.Up: canvas1.Margin = new Thickness(
canvas1.Margin.Left,
canvas1.Margin.Top - delta,
canvas1.Margin.Right,
canvas1.Margin.Bottom + delta);
break;
case Key.Right: canvas1.Margin = new Thickness(
canvas1.Margin.Left,
canvas1.Margin.Top,
canvas1.Margin.Right - delta,
canvas1.Margin.Bottom);
break;
case Key.Down: canvas1.Margin = new Thickness(
canvas1.Margin.Left,
canvas1.Margin.Top + delta,
canvas1.Margin.Right,
canvas1.Margin.Bottom - delta);
break;
default:
break;
}
}
}
贝娄是鼠标后的执行日志按下控件和三个“keyUp”:
canvas_MouseDown 0, canvas1.IsFocused? False ' before click '
canvas_MouseDown 1, canvas1.IsFocused? True ' after click '
Window_PreviewKeyDown, canvas1.IsFocused? True ' up 1 '
canvas_PreviewKeyDown, canvas1.IsFocused? True ' up 1 '
Window_PreviewKeyDown, canvas1.IsFocused? False ' up 2 '
Window_PreviewKeyDown, canvas1.IsFocused? False ' up 3 '
Say, I need to move a custom (User)Control in a form, using the keyboard.
The behavior is simple: the user clicks the control, then it can move it using the keyboard (up/d/l/r).
In this sample instead of a UserControl, I will use a Canvas.
The problem is that when I "focalize" my control, or I loose it after a coup of 'steps' for the textBox, or I don't recieve it at all...
XAML:
<Window x:Class="WpfApplication14.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
PreviewKeyDown="Window_PreviewKeyDown">
<Grid>
<TextBox Name="textBox1"
Margin="91,66,292,223" Width="120"
Text="Good morning, miss Hilton!"/>
<Canvas Name="canvas1" Focusable="True"
Margin="124,112,179,99" Width="200"
Background="AliceBlue"
MouseDown="canvas1_MouseDown"
PreviewKeyDown="canvas1_PreviewKeyDown" />
</Grid>
</Window>
CS:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void canvas1_MouseDown(object sender, MouseButtonEventArgs e)
{
Console.WriteLine("canvas_MouseDown 0, canvas1.IsFocused? {0}",
canvas1.IsFocused);
canvas1.Focus();
Console.WriteLine("canvas_MouseDown 1, canvas1.IsFocused? {0}",
canvas1.IsFocused);
}
private void canvas1_PreviewKeyDown(object sender, KeyEventArgs e)
{
Console.WriteLine("canvas_PreviewKeyDown, canvas1.IsFocused? {0}",
canvas1.IsFocused);
if (canvas1.IsFocused)
MoveCanvas(e.Key);
}
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
//Console.WriteLine("Window_PreviewKeyDown, canvas1.IsFocused? {0}",
// canvas1.IsFocused);
//if (canvas1.IsFocused)
// MoveCanvas(e.Key);
}
void MoveCanvas(Key key)
{
int delta = 10;
switch (key)
{
case Key.Left: canvas1.Margin = new Thickness(
canvas1.Margin.Left - delta,
canvas1.Margin.Top,
canvas1.Margin.Right,
canvas1.Margin.Bottom);
break;
case Key.Up: canvas1.Margin = new Thickness(
canvas1.Margin.Left,
canvas1.Margin.Top - delta,
canvas1.Margin.Right,
canvas1.Margin.Bottom + delta);
break;
case Key.Right: canvas1.Margin = new Thickness(
canvas1.Margin.Left,
canvas1.Margin.Top,
canvas1.Margin.Right - delta,
canvas1.Margin.Bottom);
break;
case Key.Down: canvas1.Margin = new Thickness(
canvas1.Margin.Left,
canvas1.Margin.Top + delta,
canvas1.Margin.Right,
canvas1.Margin.Bottom - delta);
break;
default:
break;
}
}
}
Bellow is the execution log after mouse down on the control and three "keyUp"s:
canvas_MouseDown 0, canvas1.IsFocused? False ' before click '
canvas_MouseDown 1, canvas1.IsFocused? True ' after click '
Window_PreviewKeyDown, canvas1.IsFocused? True ' up 1 '
canvas_PreviewKeyDown, canvas1.IsFocused? True ' up 1 '
Window_PreviewKeyDown, canvas1.IsFocused? False ' up 2 '
Window_PreviewKeyDown, canvas1.IsFocused? False ' up 3 '
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以尝试以下两件事:
如果您正在处理事件,请将 e.Handled 设置为 true。这应该可以防止其他事件对击键做出反应。
您可能需要使用 所有祖先控件上的 KeyboardNavigation.DirectionalNavigation 设置。默认情况下,箭头键将移动键盘焦点,但这基于 DirectionalNavigation 设置。您希望将其设置为“无”,但这假设#1 无法解决问题。
Two things you can try:
Set e.Handled to true if you are handing the event. This should prevent other things from reacting to the key stroke as well.
You may need to play around with the KeyboardNavigation.DirectionalNavigation setting on all the ancestor controls. The arrow keys by default will move the keyboard focus, but that's based on the DirectionalNavigation setting. You'd want to set it to None, but this is assuming #1 doesn't correct the issue.