I have a Control inside a Canvas and I want to be able to move it using the arrow keys. For the sake of trying things out, I created the following class, which does what I want.
<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>
Here's a snippet of the code-behind:
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);
}
This all works fine, but what I really want is a bunch of Buttons with this ability, not just that one. How can I make sure every button has these CommandBindings? If there's an easier way than using CommandBindings, what might that be?
Update: By request, here is another method that doesn't seem to work:
<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);
}
Update: I gave up on this approach. I ended up using a different solution for the problem, one that doesn't use commands.