Handle keyboard events in Silverlight

Hi,

I’m trying to use the F2 keyboard key in order to set the textEditable property to TRUE on a node of my diagram.

When i try to handle the keyboard key event on my NodePanel object, nothing happen. The keyboard event seem to be consume by someone else.

When i try to handle the keyboard key event, in my diagram, i got something ! But i’m not able to retrieve the TextBlock on which i would like to set the textEditable property to TRUE for my selected node. I’m only able to get the SelectedNode as a Node type object, but not the NodePanel which is right under it in the xaml dataTemplate definition.

<DataTemplate x:Key="Standard">
            <go:SpotPanel Style="{StaticResource SpotPanelStyle}"
                      go:Node.Location="{Binding Path=Data.Location, Mode=TwoWay}"
                      MouseEnter="Node_MouseEnter" MouseLeave="Node_MouseLeave">
                <go:NodePanel Sizing="Auto" go:SpotPanel.Main="True" MouseLeftButtonDown="NodePanel_MouseLeftButtonDown" MouseLeftButtonUp="NodePanel_MouseLeftButtonUp">
                    <Path x:Name="Shape" Style="{StaticResource NodeShapeStyle}"
                go:NodePanel.Figure="{Binding Path=Data.Figure}" />
                    <TextBlock Style="{StaticResource TextBlockStyle}"
                       Text="{Binding Path=Data.Text, Mode=TwoWay}" />
                    <ToolTipService.ToolTip>
                        <ToolTip>
                            <TextBlock Text="{Binding Path=Data.ToolTipText}" />
                        </ToolTip>                           
                    </ToolTipService.ToolTip>
                </go:NodePanel>
    </go:SpotPanel>
</DataTemplate>

I have read in the introduction to GoXam pdf that there is a CommandHandler which handle keyboard command, but i’m don’t understand how to use it to handle my F2 key and start rename my node.

Can someone give me some hints on how to handle my F2 keyboard key ? And understanding the whole keyboard key handling system ?

And i’m not able to catch Directional UP, DOWN, LEFT, RIGHT key as well…i would like to use it to move my node. Is there something special about these keys ?

First, a few minor points:

Panels cannot get focus, so they won’t get keyboard events.

The CommandHandler already handles the F2 key as the Edit command; this calls CommandHandler.Edit().

CommandHandler.Edit() looks at the first Part for which Part.CanEdit() is true. It then looks within that Part for the first TextBlock that has the Part.TextEditable attached property set to true. If it finds such a TextBlock, it starts in-place text editing by using the Diagram.TextEditingTool.

So I don’t understand why you are trying to have F2 set Part.TextEditable to true. That property is meant to enable in-place editing, not to start it. Perhaps you are trying to do something else?

So F2, should be automagically already working. Good news !

But i’m doing something wrong then. The first idea was to enable DoubleClick on node to be able to do an action. The double click is handled in my NodePanel_MouseLeftButtonDown() method. So, because the textEditingTool start on a click when the node is Selected, i have set the TextEditable property to FALSE in the NodePanel_MouseLeftButtonDown() method. This enable me to double click a selected node without having to deal with TextEditingTool.

Considering this, i wanted to enable again the TextEditable property of this node, when i hit the F2 key.

But i assume this isn’t the right way to do this.

So the right question is : how to be able to NOT start the textEditingTool when i click a selected node ?

If i can do that, i will be able to use the default F2 key behavior (the one you describe previously).

OK, now I understand you.

You just need to customize the TextEditingTool to do nothing on a click.

[code] myDiagram.TextEditingTool = new NoClickTextEditingTool();

public class NoClickTextEditingTool : Northwoods.GoXam.Tool.TextEditingTool {
public override bool CanStart() { return false; }
}[/code]
This leaves a TextEditingTool for the Diagram to use for in-place editing, but prevents that tool from being started by a mouse event.

I forgot to answer your other question, about arrow keys.

Yes, those keys are handled specially by Silverlight, depending on the circumstances. Basically, they are being handled by the ScrollViewer that the standard ControlTemplate generates. So a KeyDown event handler on the Diagram or on the Page won’t see any arrow key events.

But you can still get the event by doing:

[code] myDiagram.AddHandler(UIElement.KeyDownEvent, new KeyEventHandler(myDiagram_KeyDown), true);

void myDiagram_KeyDown(object sender, KeyEventArgs e) {
  if (e.Key == Key.Down || e.Key == Key.Up || e.Key == Key.Right || e.Key == Key.Left) {
    myDiagram.StartTransaction("move selection");
    foreach (Part part in myDiagram.SelectedParts) {
      Node n = part as Node;
      if (n == null) continue;
      Point pos = n.Position;
      switch (e.Key) {
        case Key.Down: n.Move(new Point(pos.X, pos.Y+10), false); break;
        case Key.Up: n.Move(new Point(pos.X, pos.Y-10), false); break;
        case Key.Right: n.Move(new Point(pos.X+10, pos.Y), false); break;
        case Key.Left: n.Move(new Point(pos.X-10, pos.Y), false); break;
      }
    }
    myDiagram.CommitTransaction("move selection");
  }[/code]

Note that the arrow keys will still be processed by the ScrollViewer. Either remove the ScrollViewer from the ControlTemplate or disable the ScrollViewer. If you want smarter ScrollViewer arrow key handling, you’ll have to customize the ScrollViewer itself. I haven’t tried that, so I can’t say for sure that that will work.

Allright ! Thanks for your help !
I’m now able to handle node renaming as i wanted. :)

About arrow keys, i will try it later and let you know.

The arrow keys tip work as well. Thanks.

See you soon on another topic :)

We will add a DiagramTool.MouseEnabled property in v1.1 that controls whether the CanStart() predicate can return true.

So instead of defining a custom TextEditingTool, you’ll be able to do something like:

<go:Diagram . . .> <go:Diagram.TextEditingTool> <gotool:TextEditingTool MouseEnabled="False" /> </go:Diagram.TextEditingTool> </go:Diagram>
This new property will also be useful in Silverlight where there is no <x:Null /> element. In WPF one can remove a Diagram tool property in XAML by setting it to null. With this new MouseEnabled property, for most cases one will be able to get the same effect by setting MouseEnabled=“False”, and that will work in both Silverlight XAML and in WPF XAML.

(The TextEditingTool is uncommon in that it is useful even if not startable using a mouse, because it can be invoked by the Edit command. The DraggingTool also might be used for moving parts.)