2010-10-21 27 views
0

我在Canvas中有一个控件,我希望能够使用箭头键移动它。为了解决问题,我创建了以下课程,这是我想要的。将同一组命令附加/绑定到多个控件

<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.InputBindings> 
      <KeyBinding Key="Down" Command="MoveDown" /> 
      <KeyBinding Key="Up" Command="MoveUp" /> 
      <KeyBinding Key="Right" Command="MoveRight" /> 
      <KeyBinding Key="Left" Command="MoveLeft" /> 
     </Canvas.InputBindings> 
     <Button> 
      <Button.CommandBindings> 
       <CommandBinding Command="MoveDown" Executed="MoveDown_Executed" /> 
       <CommandBinding Command="MoveUp" Executed="MoveUp_Executed" /> 
       <CommandBinding Command="MoveLeft" Executed="MoveLeft_Executed" /> 
       <CommandBinding Command="MoveRight" Executed="MoveRight_Executed" /> 
      </Button.CommandBindings> 
     </Button> 
    </Canvas> 
</Window> 

这里是后台代码片段:

private void MoveDown_Executed(object sender, ExecutedRoutedEventArgs e) 
{ 
    var uiElement = (UIElement)sender; 
    double value = Canvas.GetTop(uiElement); 
    value = Double.IsNaN(value) ? 0 : value; 
    value++; 
    Canvas.SetTop(uiElement, value < 0 ? 0 : value); 
} 

这一切工作正常,但我真正想要的是具有这种能力,不只是一个一堆按钮。我怎样才能确保每个按钮都有这些CommandBindings?如果有比使用CommandBindings更简单的方法,那可能是什么?

更新:根据要求,这里是另一个似乎并没有工作方法:

<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"> 
    <Window.CommandBindings> 
     <CommandBinding Command="MoveDown" Executed="MoveDown_Executed" /> 
     <CommandBinding Command="MoveUp" Executed="MoveUp_Executed" /> 
     <CommandBinding Command="MoveLeft" Executed="MoveLeft_Executed" /> 
     <CommandBinding Command="MoveRight" Executed="MoveRight_Executed" /> 
    </Window.CommandBindings> 
    <Window.InputBindings> 
     <KeyBinding Key="Down" Command="MoveDown" /> 
     <KeyBinding Key="Up" Command="MoveUp" /> 
     <KeyBinding Key="Right" Command="MoveRight" /> 
     <KeyBinding Key="Left" Command="MoveLeft" /> 
    </Window.InputBindings> 
    <Canvas > 
     <Button Width="50" Height="50" /> 
    </Canvas> 
</Window> 

C#

private void MoveDown_Executed(object sender, ExecutedRoutedEventArgs e) 
{ 
    var uiElement = (UIElement)e.OriginalSource; // Still doesn't point to the Button 
    double value = Canvas.GetTop(uiElement); 
    value = Double.IsNaN(value) ? 0 : value; 
    value++; 
    Canvas.SetTop(uiElement, value < 0 ? 0 : value); 
} 

更新:我放弃了这种做法。我最终使用了一个different solution来解决这个问题,一个不使用命令的问题。

回答

0

你应该在路由事件处理程序来看一看:http://msdn.microsoft.com/en-us/library/ms742806.aspx

上面的链接有如何做你的要求的例子。

<Border Height="50" Width="300" BorderBrush="Gray" BorderThickness="1"> 
    <StackPanel Background="LightGray" Orientation="Horizontal" Button.Click="CommonClickHandler"> 
    <Button Name="YesButton" Width="Auto" >Yes</Button> 
    <Button Name="NoButton" Width="Auto" >No</Button> 
    <Button Name="CancelButton" Width="Auto" >Cancel</Button> 
    </StackPanel> 
</Border> 

和代码

private void CommonClickHandler(object sender, RoutedEventArgs e) 
{ 
    FrameworkElement feSource = e.Source as FrameworkElement; 
    switch (feSource.Name) 
    { 
    case "YesButton": 
     // do something here ... 
     break; 
    case "NoButton": 
     // do something ... 
     break; 
    case "CancelButton": 
     // do something ... 
     break; 
    } 
    e.Handled=true; 
} 
+0

这听起来很有希望,只有没有我使用的命令(即Button有Click事件,但没有Button.MoveUp,Button.MoveDown等)的事件。我将不得不阅读这些信息,看看我能否实现它。 – Pat 2010-10-21 21:23:28

+0

我猜路由事件真的是我去的解决方案:http://stackoverflow.com/questions/3992278/move-a-control-inside-a-canvas-using-directional-keys/3998438#3998438 – Pat 2010-10-22 15:48:51

0

如果你创建(在这种情况下,窗口)的顶级对象化CommandBindings,你就能够重复使用他们为窗口的任何子女。

<Window x:Class="TesterApp.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:data="clr-namespace:TesterApp" 
     x:Name="TheMainWindow" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
    </Window.Resources> 
    <Window.InputBindings> 
     <KeyBinding Key="A" Command="MoveDown" /> 
    </Window.InputBindings> 
    <Window.CommandBindings> 
     <CommandBinding Command="MoveDown" Executed="MoveDown_Executed" /> 
    </Window.CommandBindings> 
    <Grid> 
     <Button Height="30" Width="80" Content="Click" Command="MoveDown" /> 
    </Grid> 
</Window> 
+0

问题是事件的'sender'不是Button本身,而是CommandBinding的高级控件。我需要对Button自身的引用,所以我可以使用Canvas.SetTop等来移动它。 – Pat 2010-10-21 21:14:34

+0

检查ExecutedRoutedEventArgs参数的OriginalSource属性。 – mdm20 2010-10-21 21:17:46

+0

哦,如果只有这个工作!对于OriginalSource,我仍然得到Canvas(这是我定义Command-和Input-Bindings的地方)而不是Button。 – Pat 2010-10-21 21:29:07

相关问题