We have a solution where we need be able to only tab between editable cells in a grid. The default behavior of the tab is to select the next cell in the grid. Is there any way to override this, so that clicking tab the grid will select the next editable cell in the grid?
Regards
Bjarne
Here's one way to achieve the skipping of cells. It uses the ActiveCellChanged event of the XamGrid. Some further work could be done to improve it.
void theGrid_ActiveCellChanged(object sender, EventArgs e) { int currindex = 0; if (YOUR LOGIC HERE COMPARING IF THE CELL SHOULD BE SKIPPED) { foreach (Infragistics.Controls.Grids.Cell cell in theGrid.ActiveCell.Row.Cells) { if (cell.IsActive) { if ((theGrid.Rows[theGrid.ActiveCell.Row.Index].Cells.Count - 1) > currindex) { theGrid.Rows[theGrid.ActiveCell.Row.Index].Cells[currindex + 1].IsActive = true; theGrid.Rows[theGrid.ActiveCell.Row.Index].Cells[currindex + 1].IsSelected = true; return; } else { if ((theGrid.Rows.Count - 1) >= theGrid.ActiveCell.Row.Index) return; theGrid.Rows[theGrid.ActiveCell.Row.Index + 1].Cells[0].IsActive = true; theGrid.Rows[theGrid.ActiveCell.Row.Index].Cells[currindex + 1].IsSelected = true; return; } } currindex++; } } }
Thanks for the code, but I don't get it to work. I have slightly different scenario because I have grouped grid but I think it should work with this kind of code. I have simplified it a bit.
RowBase row = EntryGrid.ActiveCell.Row; int currIndex = 0; if (IS TO BE SKIPPED) { foreach (Cell cell in row.Cells) { if (cell.IsActive) { if ((row.Cells.Count - 1) > currIndex) { row.Cells[currIndex + 1].IsActive = true; row.Cells[currIndex + 1].IsSelected = true; return; } return; } currIndex++; } }
The problem is that after I've changed the IsActive to true for the next cell, something changes it back to the previous. My callstack just says it's external code before coming again to ActiveCellChanged (of course it comes there once after the first change). I've removed all the other code related to my Grid to eliminate other causes for this kind of behaviour. Should the IsActive be set to False first before setting it to true for other column? Any other ideas?
anttisimonen,
The piece of code I posted yesterday works for non-grouped data, even your cleaned up version works pretty good in my test project. Once I get a little more time I'll try some deeper debugging to see if I can work in grouped rows as well.
I think I've found what is breaking my project. I did a new sample project to see what breaks it and found out that setting IsOnCellActiveEditingEnabled to True, breaks your code. Without that it works fine.
Can you try with IsOnCellActiveEditingEnabled=True and see if you can break your code? And of course if you can find a solution how to make it work with that too :) Thanks again!
anttisimonen said: I think I've found what is breaking my project. I did a new sample project to see what breaks it and found out that setting IsOnCellActiveEditingEnabled to True, breaks your code. Without that it works fine. Can you try with IsOnCellActiveEditingEnabled=True and see if you can break your code? And of course if you can find a solution how to make it work with that too :) Thanks again!
That means your cell enters edit mode on each new cell activation. What we'd need to do is tell it to exit edit mode before the active cell change.
RowBase row = EntryGrid.ActiveCell.Row; int currIndex = 0; if (IS TO BE SKIPPED) { foreach (Cell cell in row.Cells) { if (cell.IsActive) { if ((row.Cells.Count - 1) > currIndex) { EntryGrid.ExitEditMode(false); row.Cells[currIndex + 1].IsActive = true; row.Cells[currIndex + 1].IsSelected = true; return; } return; } currIndex++; } }
Let me know if that does the trick for you?
Thanks! That solved it!
I had to tweak your code a bit. I don't want to enter edit mode every time. Just when I don't skip the cell so the final code that works is like this:
if (IS TO BE SKIPPED) { foreach (Cell cell in row.Cells) { if (cell.IsActive) { if ((row.Cells.Count - 1) > currIndex) { row.Cells[currIndex + 1].IsActive = true; row.Cells[currIndex + 1].IsSelected = true; return; } return; } currIndex++; } } else { EntryGrid.EnterEditMode(EntryGrid.ActiveCell); }
Thank you for your efforts on solving this!
I found a way that should work for your implementation.
1. Set IsOnCellActiveEditingEnabled to false, or just remove that line of code.
2. Use the snippet of code below.
void theGrid_ActiveCellChanged(object sender, EventArgs e) { int currindex = 0; RowBase row = theGrid.ActiveCell.Row; theGrid.EnterEditMode(theGrid.ActiveCell); if (IS TO BE SKIPPED) { foreach (Cell cell in row.Cells) { if (cell.IsActive) { if ((row.Cells.Count - 1) > currindex) { row.Cells[currindex + 1].IsActive = true; row.Cells[currindex + 1].IsSelected = true; return; } } currindex++; } } }
The EnterEditMode method that gets called on the ActiveCell simulates the IsOnCellActiveEditingEnabled functionality you wanted to use, while allowing you to skip cells that are logically not editable.
Here's the sample project attached. You need to re-add your IG references there. I've used 10.3 versions so I don't know if this behavior is already fixed in 11.1?
Doesn't work. Maybe the cell is not in the edit mode just yet or something? The result is still that the cell which should be skipped is stealing back the active cell right after it's set to the next one. So it will be an endless loop and finally results in StackOverFlowException...