Edit Mode and the KeyboardCommandProvider

17 posts, 0 answers
  1. Dave
    Dave avatar
    23 posts
    Member since:
    Feb 2010

    Posted 24 Aug 2010 Link to this post

    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>

  2. Maya
    Admin
    Maya avatar
    4062 posts

    Posted 25 Aug 2010 Link to this post

    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
  3. UI for WPF is Visual Studio 2017 Ready
  4. Dave
    Dave avatar
    23 posts
    Member since:
    Feb 2010

    Posted 25 Aug 2010 Link to this post

    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.




       
  5. Maya
    Admin
    Maya avatar
    4062 posts

    Posted 26 Aug 2010 Link to this post

    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
  6. Dave
    Dave avatar
    23 posts
    Member since:
    Feb 2010

    Posted 30 Aug 2010 Link to this post

    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
  7. Maya
    Admin
    Maya avatar
    4062 posts

    Posted 02 Sep 2010 Link to this post

    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
  8. Dave
    Dave avatar
    23 posts
    Member since:
    Feb 2010

    Posted 02 Sep 2010 Link to this post

    Maya,

    THANK YOU! This is EXACTLY what I needed.

    Cheers,
    Dave
  9. Michael
    Michael avatar
    8 posts
    Member since:
    Jul 2010

    Posted 10 Sep 2010 Link to this post

    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.
  10. Maya
    Admin
    Maya avatar
    4062 posts

    Posted 15 Sep 2010 Link to this post

    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
  11. Michael
    Michael avatar
    8 posts
    Member since:
    Jul 2010

    Posted 15 Sep 2010 Link to this post

    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
  12. Maya
    Admin
    Maya avatar
    4062 posts

    Posted 16 Sep 2010 Link to this post

    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
  13. Michael
    Michael avatar
    8 posts
    Member since:
    Jul 2010

    Posted 16 Sep 2010 Link to this post

    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.
  14. Maya
    Admin
    Maya avatar
    4062 posts

    Posted 16 Sep 2010 Link to this post

    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
  15. Vinay Khandelwal
    Vinay Khandelwal avatar
    1 posts
    Member since:
    Jun 2010

    Posted 08 Dec 2010 Link to this post

    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
  16. Maya
    Admin
    Maya avatar
    4062 posts

    Posted 13 Dec 2010 Link to this post

    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
  17. ajoua taha
    ajoua taha avatar
    25 posts
    Member since:
    Feb 2016

    Posted 07 Mar Link to this post

    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 
  18. Maya
    Admin
    Maya avatar
    4062 posts

    Posted 08 Mar Link to this post

    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
Back to Top
UI for WPF is Visual Studio 2017 Ready