5

I am using Winform's PropertyGrid in my project, it all works fine but the tab order.

I want to switch to next property when I hit Tab but infact, selection moves out of property grid to next control. I am not able to figure out how to get this done ?

Thanks

Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
Muds
  • 4,006
  • 5
  • 31
  • 53

1 Answers1

5

We should dig into internal parts of PropertyGrid then we can change default Tab behavior of control. At start we should create a derived PropertyGrid and override its ProcessTabKey method.

In the method, first find the internal PropertyGridView control which is at index 2 in Controls collection. Then using Reflection get its allGridEntries field which is a collection containing all GridItem elements.

After finding all grid items, find the index of SelectedGridItem in the collection and check if it's not the last item, get the next item by index and select it using Select method of the item.

using System.Collections;
using System.Linq;
using System.Windows.Forms;
public class ExPropertyGrid : PropertyGrid
{
    protected override bool ProcessTabKey(bool forward)
    {
        var grid = this.Controls[2];
        var field = grid.GetType().GetField("allGridEntries",
            System.Reflection.BindingFlags.NonPublic |
            System.Reflection.BindingFlags.Instance);
        var entries = (field.GetValue(grid) as IEnumerable).Cast<GridItem>().ToList();
        var index = entries.IndexOf(this.SelectedGridItem);

        if (forward && index < entries.Count - 1)
        {
            var next = entries[index + 1];
            next.Select();
            return true;
        }
        return base.ProcessTabKey(forward);
    }
}
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • Thanks for your answer Reza, but somehow ProcessTabKey is not hit when I press Tab. – Muds Jul 18 '16 at 08:40
  • Probably you have made a mistake. You should add this class to your project and put an instance of it on your form. I tested it and it I'me sure it works properly, so let me know if you have any problem applying the answer :) – Reza Aghaei Jul 18 '16 at 08:58
  • yea Reza that's what I have done, may be tab is handled elsewhere and doesn't let processTab execute ? I don't know what is the order of processing tab key but something is stopping tab to not propogate – Muds Jul 18 '16 at 09:01
  • It's good to test it in a clean form/project and let me know the result :) – Reza Aghaei Jul 18 '16 at 09:02
  • I also tested it again in visual studio 2010 and visual studio 2013 :) Make sure you are dropping the new control we created **`ExPropertyGrid`** control on the form not the original property grid. – Reza Aghaei Jul 18 '16 at 09:06
  • Hi Reza, I got this working partially as this PropertyGrid is hosted inside WPF Control hence I guess there are some issues, but one thing I wanted to check, if I press tab, it selects Property Name not the Value, can I make it select value everytime I press tab ? – Muds Jul 18 '16 at 10:29
  • Hi Muds, I don't have any idea about why it doesn't work properly in WPF, you may want to ask another question about that. About selecting the next label using `Tab`. What is the expected behavior when the focus is on label part of a property. What't the expected behavior when the focus in on value part of a property? Let me know and I'll check for it's feasibility :) – Reza Aghaei Jul 18 '16 at 15:17
  • I think the best would be to always move focus between editable areas, when property names are not editable why move focus on it isn't ? – Muds Jul 18 '16 at 15:25
  • While the current solution moves between both label and editable area, if the focus in on label area as soon as you try to type something, the focus will be moved to edit area and you don't need to do anything else. Do we need any further try? – Reza Aghaei Jul 18 '16 at 15:29
  • i think i am expecting too much from one answer, kudos man, atleast i got a way! marks your answer! – Muds Jul 18 '16 at 15:51
  • You're welcome and thanks for the feedback, you also have my vote :) – Reza Aghaei Jul 18 '16 at 15:56
  • To allow the tabs to start from the beginning again, I added this after the "if" `else if (entries.Count>0) {var next = entries[0]; next.Select(); return true;}` – JasonH Feb 09 '17 at 22:45
  • 1
    Great answer! For others, if you want to handle forward = false `if (!forward && index > 0) { var previous = entries[index - 1]; previous.Select(); return true; }` – edhubbell Feb 09 '21 at 19:40