我在畫布元素內有許多控件,我希望能夠使用箭頭/方向鍵(上,下,左,右)在畫布內移動它們。在WPF /代碼隱藏中最簡單的方法是什麼?有沒有一個習慣WPF的方式做到這一點?使用方向鍵在畫布內移動控件
我想我應該澄清:我想能夠獨立移動每個控件;我不想同時移動所有的控件。
我在畫布元素內有許多控件,我希望能夠使用箭頭/方向鍵(上,下,左,右)在畫布內移動它們。在WPF /代碼隱藏中最簡單的方法是什麼?有沒有一個習慣WPF的方式做到這一點?使用方向鍵在畫布內移動控件
我想我應該澄清:我想能夠獨立移動每個控件;我不想同時移動所有的控件。
這裏是我的解決方案:
首先,捕捉按鍵事件
EventManager.RegisterClassHandler(typeof(MainWindow), UIElement.KeyDownEvent, new KeyEventHandler(KeyDownHandler));
然後找出誰發送的事件,並相應地移動。
void KeyDownHandler(object sender, KeyEventArgs e)
{
UIElement element = e.OriginalSource as UIElement;
if (element != null)
{
double left = Canvas.GetLeft(element);
if (Double.IsNaN(left)) left = 0;
double top = Canvas.GetTop(element);
if (Double.IsNaN(top)) top = 0;
switch (e.Key)
{
case Key.Left: left--; break;
case Key.Right: left++; break;
case Key.Up: top--; break;
case Key.Down: top++; break;
}
Canvas.SetLeft(element, left);
Canvas.SetTop(element, top);
}
e.Handled = true;
}
我能夠做到這一點是這樣的:
修訂:現在只能移動一個與焦點(和處理事件進一步停止窗口)。
private void Window_KeyDown(object sender, KeyEventArgs e)
{
int deltaX = 0, deltaY = 0;
if (e.Key == Key.Left)
{
deltaX = -1;
}
else if (e.Key == Key.Right)
{
deltaX = 1;
}
else if (e.Key == Key.Up)
{
deltaY = -1;
}
else if (e.Key == Key.Down)
{
deltaY = 1;
}
foreach (UIElement element in this.canvas1.Children)
{
if (element.IsFocused)
{
double left = (double)element.GetValue(Canvas.LeftProperty);
element.SetValue(Canvas.LeftProperty, left + deltaX);
double top = (double)element.GetValue(Canvas.TopProperty);
element.SetValue(Canvas.TopProperty, top + deltaY);
}
}
e.Handled = true;
}
我接受@ mdm20的解決方案,但是我的實際實現有些不同。首先,我不想處理所有的KeyDown事件(例如Tab不應該被處理)。 (有趣的是,我發現,這種方法可用於移動整個窗口)
public CanvasControlArrowKeyTest()
{
InitializeComponent();
EventManager.RegisterClassHandler(typeof(Window), UIElement.KeyDownEvent, new KeyEventHandler(HandleKeyDown));
}
private void HandleKeyDown(object sender, KeyEventArgs e)
{
UIElement element = e.OriginalSource as UIElement;
if (element != null)
{
double left = Canvas.GetLeft(element);
if (Double.IsNaN(left)) left = 0;
double top = Canvas.GetTop(element);
if (Double.IsNaN(top)) top = 0;
switch (e.Key)
{
case Key.Left: left--; break;
case Key.Right: left++; break;
case Key.Up: top--; break;
case Key.Down: top++; break;
default: return;
}
if (left < 0) left = 0;
if (top < 0) top = 0;
Canvas.SetLeft(element, left);
Canvas.SetTop(element, top);
e.Handled = true;
}
}
作爲參考,這裏的XAML:
<Window x:Class="DiagramDesigner.CanvasControlArrowKeyTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="CanvasControlArrowKeyTest" Height="300" Width="300">
<Canvas>
<Canvas.Resources>
<Style TargetType="Button">
<Setter Property="Width" Value="50" />
<Setter Property="Height" Value="50" />
<Setter Property="Background" Value="Black"/>
</Style>
</Canvas.Resources>
<Button />
<Button />
</Canvas>
</Window>
if (e.keycode == keys.right)
{
rectangle2.left = rectangle2.left + 25;
ellipse1.left = ellipse1.left + 25;
}
else if (e.keycode == keys.left)
{
rectangle2.left = rectangle2.left - 25;
ellipse1.left = ellipse1.left - 25;
}
要以及移動矩形爲橢圓形,使用此...
<Window x:Class="Wpf_Game.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Shootings" Height="700" Width="900" KeyDown="Window_KeyDown" KeyUp="Window_KeyUp">
private void Window_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Left)
{
var l = Canvas.GetLeft(rectangle1);
Canvas.SetLeft(rectangle1,l-20);
Canvas.SetLeft(ellipse1,l-20);
}
else if (e.Key == Key.Right)
{
var l = Canvas.GetLeft(rectangle1);
Canvas.SetLeft(rectangle1, l + 20);
Canvas.SetLeft(ellipse1, l + 20);
}
else if (e.Key == Key.Enter)
{
Canvas.SetTop(ellipse1,05);
}
}
一個更加想法是
if(Canvas.TopProperty==IsActiveProperty)
{
Canvas.SetLeft(ellipse1,l-20);
}
謝謝..工作真棒。 – SST 2012-10-26 10:04:16