2010-10-21 37 views
2

我在畫布元素內有許多控件,我希望能夠使用箭頭/方向鍵(上,下,左,右)在畫布內移動它們。在WPF /代碼隱藏中最簡單的方法是什麼?有沒有一個習慣WPF的方式做到這一點?使用方向鍵在畫布內移動控件

我想我應該澄清:我想能夠獨立移動每個控件;我不想同時移動所有的控件。

回答

4

這裏是我的解決方案:

首先,捕捉按鍵事件

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; 
} 
+0

謝謝..工作真棒。 – SST 2012-10-26 10:04:16

1

我能夠做到這一點是這樣的:

修訂:現在只能移動一個與焦點(和處理事件進一步停止窗口)。

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; 
} 
+0

更新我的問題:我想我應該澄清:我想能夠獨立移動每個控件;我不想同時移動所有的控件。因此,我需要知道哪些控件要移動(即哪個控件有焦點)。 – Pat 2010-10-21 22:13:24

+0

已更新。這是你在找什麼? – steinar 2010-10-21 22:20:11

+0

是的,我認爲這會奏效。不過,我沒有使用它,因爲@ mdm20的解決方案不依賴迭代。另外,我會用LINQ語句'.Where(e => e.IsFocused)'替換你的答案中的foreach。 – Pat 2010-10-22 15:33:23

1

我接受@ 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> 
0
 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; 
     } 
-2

要以及移動矩形爲橢圓形,使用此...

<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); 
      } 
     } 
-1

一個更加想法是

if(Canvas.TopProperty==IsActiveProperty) 
       { 
       Canvas.SetLeft(ellipse1,l-20); 
       }