This is a migrated thread and some comments may be shown as answers.

Edit Mode and the KeyboardCommandProvider

16 Answers 819 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Dave
Top achievements
Rank 1
Dave asked on 24 Aug 2010, 07:18 PM
I need to provide arrow key navigation between rows and columns similar to how Excel works. I have implemented a custom keyboard command provided based on DefaultKeyboardCommandProvider following the instructions from this blog post (the example is actually incorrect. After clearing the command list, the example tried to Remove rather than Add a RadGridViewCommands command to this list).

It appears that if the cell is in edit mode, the custom command provider does not pick up the keyboard events. If I press ESC to cancel edit mode, then the provide gets called. Is there some problem with how I have defined my XAML? I would expect the "Key.Up" and "Key.Down" keys to propogate through the edit control (TextBox) and through to the command provider. Here's what the XAML looks like for the column I'm testing:

                <trgv:GridViewDataColumn Header="Quantity"
 MinWidth="75"
 HeaderTextAlignment="Right"
 ShowDistinctFilters="False">
                    <trgv:GridViewDataColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Quantity}"
   HorizontalAlignment="Right"/>
                        </DataTemplate>
                    </trgv:GridViewDataColumn.CellTemplate>
                    <trgv:GridViewDataColumn.CellEditTemplate>
                        <DataTemplate>
                            <infctrl:NumberTextBox Value="{Binding Quantity, ValidatesOnDataErrors=True, UpdateSourceTrigger=LostFocus}"
   HorizontalAlignment="Stretch"
   DisplayFormat="N0"/>
                        </DataTemplate>
                    </trgv:GridViewDataColumn.CellEditTemplate>
                </trgv:GridViewDataColumn>

16 Answers, 1 is accepted

Sort by
0
Maya
Telerik team
answered on 25 Aug 2010, 12:06 PM
Hi Dave Kehring,

Following up the example in the blog post, the edit-mode of the cell is not propagated on using Key.Up and Key.Down in case the Clear() method is called upon the commandsToExecute. Otherwise, the mode of the cell is normally transferred to the next/previous ones.
So, in order to provide you with an appropriate solution, I would need a bit more information about the behavior you want to achieve on navigating with the Up and Down keys.

Regards,
Maya
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Dave
Top achievements
Rank 1
answered on 25 Aug 2010, 01:05 PM
Hi Maya,

See the attached images for more information. Here's the explanation:

In the image StateA, the cursor is in the first row of the Quantity column and the cell is in edit mode. The column is defined in XAML like this:

<trgv:GridViewDataColumn Header="Quantity"
                            MinWidth="75"
                            HeaderTextAlignment="Right"
                            ShowDistinctFilters="False">
    <trgv:GridViewDataColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Quantity}"
                        HorizontalAlignment="Right"/>
        </DataTemplate>
    </trgv:GridViewDataColumn.CellTemplate>
    <trgv:GridViewDataColumn.CellEditTemplate>
        <DataTemplate>
            <infctrl:NumberTextBox Value="{Binding Quantity, ValidatesOnDataErrors=True, UpdateSourceTrigger=LostFocus}"
                                    HorizontalAlignment="Stretch"
                                    DisplayFormat="N0"/>
        </DataTemplate>
    </trgv:GridViewDataColumn.CellEditTemplate>
</trgv:GridViewDataColumn>


You will notice that I'm using a custom control for the edit control. This control derives from TextBox and add some additional features such as numeric formatting and automatica justification when the control receives and loses focus. Even if I change this to a regular TextBox the problem still exists.

What I want to happen is when the user presses the down arrow key, the currently edited cell should commit edit mode, the cursor moves to the next row / same column and that cell is put into edit mode (see StateB image).

Now, this is an editable column. I also have read-only columns so if the user presses the left or right arrow to move from an editable column to a read-only column, the cell being moved to should not be put into edit mode. I believe I can determine this in my custom keyboard command provider by checking the IsReadOnly property of the CurrentColumn property of the grid.

Here's the current implementation of my custom keyboard command provider:

public class OrderDetailsKeyboardCommandProvider : DefaultKeyboardCommandProvider
{
    GridViewDataControl _grid;
    public OrderDetailsKeyboardCommandProvider(GridViewDataControl grid) : base(grid)
    {
        _grid = grid;
    }
    public override IEnumerable<System.Windows.Input.ICommand> ProvideCommandsForKey(System.Windows.Input.Key key)
    {
        List<ICommand> commandsToExecute = base.ProvideCommandsForKey(key).ToList();
        if (key == Key.Up)
        {
            commandsToExecute.Clear();
            if ((_grid.CurrentColumn.IsReadOnly == false) && (_grid.CurrentCell.IsInEditMode))
                commandsToExecute.Add(RadGridViewCommands.CommitEdit);
            commandsToExecute.Add(RadGridViewCommands.MoveUp);
            commandsToExecute.Add(RadGridViewCommands.SelectCurrentUnit);
            if (_grid.CurrentColumn.IsReadOnly == false)
                commandsToExecute.Add(RadGridViewCommands.BeginEdit);
        }
        if (key == Key.Down)
        {
            commandsToExecute.Clear();
            if ((_grid.CurrentColumn.IsReadOnly == false) && (_grid.CurrentCell.IsInEditMode))
                commandsToExecute.Add(RadGridViewCommands.CommitEdit);
            commandsToExecute.Add(RadGridViewCommands.MoveDown);
            commandsToExecute.Add(RadGridViewCommands.SelectCurrentUnit);
            if (_grid.CurrentColumn.IsReadOnly == false)
                commandsToExecute.Add(RadGridViewCommands.BeginEdit);
        }
        return commandsToExecute;
    }
}

The problem is that it appears the RoutedUICommand of the Key.Down / Key.Up is not being propogated to my keyboard command provider from the TextBox control used to edit the cell value. If I set a breakpoint on the first line of the ProvideCommandsForKey override it does not get hit. I suspect that somewhere we need to look at the PreviewKeyDown event rather than the KeyDown event.




   
0
Maya
Telerik team
answered on 26 Aug 2010, 02:05 PM
Hi Dave Kehring,

The reason for this behavior is indeed the TextBox that does not handle the KeyDown event. Thus the logic for setting the cell above/below in edit-mode or not is not applied. However, this is caused by the WPF native TextBox and event if you define Custom KeyboardCommandProvider, you will not be able to achieve the desired result.
What you can do is to create your own custom column, whose element handles the KeyDown event and set the cell into edit-mode. You can find an example of adding a custom column in this blog post

All the best,
Maya
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Dave
Top achievements
Rank 1
answered on 30 Aug 2010, 03:37 PM
Hi Maya,

I'm not sure this will solve my problem. As I stated, when the down or up arrow is pressed while in a column that is in edit mode, I need to cancel (or commit) editing, move up or down and then put the next column into edit mode. I need to use a TextBox-based control so your suggestion to "create your own custom column, whose element handles the KeyDown event and set the cell into edit-mode" doesn't make sense. Do you have a concrete example of how to do EXACTLY what I require? The blog post about creating a custom column does not refer at all to the handling of key presses.

This has become a critical issue for me moving forward on a project so I would appreciate a quick response.

Regards,
Dave
0
Maya
Telerik team
answered on 02 Sep 2010, 04:00 PM
Hi Dave Kehring,

 
The restriction with the edit-mode when navigating comes from the regular TextBox that handles the KeyDown event. However, you can handle the PreviewKeyDown event and define the behavior of the grid on Left/Right/Up/Down Keys using a sequence of commands.
For example, the code for the Left Key will be as follows:

private void HandleKeyLeft(KeyEventArgs e)
        {
            if (e.Key == Key.Left)
            {
                var editBox = this.playersGrid.CurrentCell.ChildrenOfType<TextBox>().FirstOrDefault();
 
                if (editBox.CaretIndex == 0)
                {
                    RadGridViewCommands.MoveLeft.Execute(null);
                    RadGridViewCommands.SelectCurrentUnit.Execute(null);
                    RadGridViewCommands.BeginEdit.Execute(null);
 
                    e.Handled = true;
                }
            }
        }

The condition of (editBox.CaretIndex=0) ensures that you are in the beginning of the TextBox and you need to go to the previous cell.
I am sending you a sample project demonstrating the implementation of that functionality.

Sincerely yours,
Maya
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Dave
Top achievements
Rank 1
answered on 02 Sep 2010, 05:44 PM
Maya,

THANK YOU! This is EXACTLY what I needed.

Cheers,
Dave
0
Michael
Top achievements
Rank 1
answered on 10 Sep 2010, 09:44 PM
I took this sample and added a GridViewMaskedTextboxColumn but the right arrow key won't move past that column.

I added a Salary property to Player like this:

public double Salary
{
    get { return this.salary; }
    set
    {
        if (value != this.salary)
        {
            this.salary = value;
            this.OnPropertyChanged("Salary");
        }
    }
}


And here's the column definitions:

<telerik:RadGridView.Columns>
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Name}"/>
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Number}"/>
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Position}"/>
                <telerik:GridViewMaskedTextBoxColumn DataMemberBinding="{Binding Salary}" MaskType="Numeric" Mask="c"/>
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Country}"/>
            </telerik:RadGridView.Columns>


Please let me know how to work around this issue.
0
Maya
Telerik team
answered on 15 Sep 2010, 02:24 PM
Hi Michael,

You can try to use the MovePrevious and MoveNext Commands instead of MoveLeft and MoveRight. In this way, once the cell in edit mode is the first/last one, navigating with the Arrow Keys will lead you to the previous/next cell, which will be again in edit mode.

Kind regards,
Maya
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Michael
Top achievements
Rank 1
answered on 15 Sep 2010, 03:45 PM
I have retested this with MoveNext and MovePrevious.

Up, down and left keys work fine. Right arrow does not. I believe this is related to PITS # 3436
0
Maya
Telerik team
answered on 16 Sep 2010, 11:54 AM
Hi Michael,

 You can make a slight change when handling the event for that key and set it as follows:

private void HandleKeyLeft(KeyEventArgs e)
{
    if (e.Key == Key.Left)
    {
        var editBox = this.playersGrid.CurrentCell.ChildrenOfType<TextBox>().FirstOrDefault();
 
        if (editBox.CaretIndex == 0 && editBox.SelectionLength == 0)
        {
            RadGridViewCommands.MovePrevious.Execute(null);                         
                        RadGridViewCommands.SelectCurrentUnit.Execute(null);                
                        RadGridViewCommands.BeginEdit.Execute(null);
 
            e.Handled = true;
        }
    }
}


Regards,
Maya
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Michael
Top achievements
Rank 1
answered on 16 Sep 2010, 01:41 PM
The problem is not with moving left, it's with moving to the right. The selection in the RadMaskedTextbox is not clearing properly so the caret is not moving to the end of the textbox.
0
Maya
Telerik team
answered on 16 Sep 2010, 01:56 PM
Hi Michael,

Firstly, please excuse me for the misunderstanding. Indeed the issue here conserns the one you pointed.Unfortunately, it has not been resolved yet. 
However, as a possible workaround, I may suggest to you to use a GridViewDataColumn and set its DataFormatString Property. For example:

<telerik:GridViewDataColumn DataMemberBinding="{Binding Salary}" 
                           DataFormatString="{}{0:c}"/>

I hope that helps.


Sincerely yours,
Maya
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Vinay Khandelwal
Top achievements
Rank 1
answered on 08 Dec 2010, 11:57 AM
Hi,

We want to provide some custom behaviour based upon some Key combination e.g. Control + C. But when Control is pressed we always get Control in the key. So we can not determine the combination.

Please suggest.

Thanks
Vinay
0
Maya
Telerik team
answered on 13 Dec 2010, 11:53 AM
Hi Vinay Khandelwal,

You may handle the PreviewKeyDown event of the grid as follows:
public MainWindow()
{
  InitializeComponent();
         
  this.clubsGrid.PreviewKeyDown += new System.Windows.Input.KeyEventHandler(clubsGrid_PreviewKeyDown);           
}
         
void clubsGrid_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
   if (e.Key == Key.C)
   {              
    if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
    {
          MessageBox.Show("Control+C keys are pressed");
    }
    }
}

 

Kind regards,
Maya
the Telerik team
Browse the videos here>> to help you get started with RadControls for WPF
0
ajoua taha
Top achievements
Rank 1
answered on 07 Mar 2016, 05:30 PM
I followed the "editmode-navigation-wpf" example , but "RadGridViewCommands.BeginEdit.Execute(null);" does't work , it just focus in cell but don't make it in edit mode 
0
Maya
Telerik team
answered on 08 Mar 2016, 08:40 AM
Hello Taha,

With the current version, you can try defining the key down method as follows:
private void HandleKeyDown(KeyEventArgs e)
        {
            if (e.Key == Key.Down)
            {
                RadGridViewCommands.CommitEdit.Execute(null);
                RadGridViewCommands.MoveDown.Execute(null);
                RadGridViewCommands.SelectCurrentUnit.Execute(null);
                this.Dispatcher.BeginInvoke((Action)(() => RadGridViewCommands.BeginEdit.Execute(null)), System.Windows.Threading.DispatcherPriority.Input);
 
                e.Handled = true;
            }
        }


Regards,
Maya
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
GridView
Asked by
Dave
Top achievements
Rank 1
Answers by
Maya
Telerik team
Dave
Top achievements
Rank 1
Michael
Top achievements
Rank 1
Vinay Khandelwal
Top achievements
Rank 1
ajoua taha
Top achievements
Rank 1
Share this question
or