Currently - selecting a cell in the Grid scrolls the entire page/form to position current row's cursor on the bottom line of screen.
The form in question has many 'yes/no radio buttons followed by grid' sets, enabling the user to select yes, then TAB into the grid and add a row. (The event on the grid to support TAB-ing is included below). The user can TAB from the prior radio button, into the first cell, then after last cell in a grid, to the next radio button following grid, click yes if appropriate and do the same actions on this grid. This works great.
The problem occurs when tabbing into a grid on the bottom of the page, or even click an existing row. The bottom grid, partially out of view must trigger something in your controls that repositions the parent form to try and set the control's Active Row (which should be the entire Grid) - into focus??
This makes the page extremely difficult to use if there is content present in these rows. If you reverse tab - or even repeatedly click between the two cells on a row and the form re-positions to the bottom the row you are clicking - till any rows that were visible (i.e. 3 valid rows that were visible below current row) - no longer are.
How it should work - Given the grid has a FIXED height of 1/6th the form height (You can view 6 radio-button/grid sets always on the screen) - If I TAB into one that is partially off the form - the form should scroll the entire grid a set height above the bottom of the form - that would show the entire grid and maintain a 'minimum' margin. Entering new rows would/should make no difference to the position of the grid - as the grid itself has its own scroll bars and its content moves up the row's height - the FORM should stays where it is when a new row is added.I believe this is possible - but need an 'expert' to tell me how to do this...
I tried: Infragistics.Win.Utilities.FocusControlWithoutScrollingIntoView(grid);in the BeforeGridRowDeactivate event (since TAB is used primarily to move through grid, OnMouseDown/Up didn't seem appropriate) - with no affect.
Can you tell me what code to use to - maybe another OnEnter event item that scrolls the grid entirely into view - and something to completely disable form autoscroll on this entire form - or fix the auto-scroll to scroll parent-container(grid) into view - and not the control (row) itself. I think I have the right ideas - but have only been using 11.2 for a couple months... Really could use some help.
Thank you, Todd
Here is the TAB handler I added just in case you want to know how I did it (since older examples on the Forum did not work - and of course I wonder if you think my method is correct: add template row if not present, set focus to the first 'IsTabStop' cell - which to me implies if it is tabbable, it is visible, then set Edit mode as one of the TAB examples showed). This does work - so posted here mainly FYI...
public static void OnGridEnter(object sender, EventArgs e){ // Select first cell UltraGrid grid = (UltraGrid)sender;try { // Select first cell in grid - Is there any rows in grid
if (grid.Rows.Count == 0){ // No - activate a new row based on template grid.Rows.TemplateAddRow.Activate();}// Set the first tab into-able cell as the current active cellfor (int i = 0; i < grid.ActiveRow.Cells.Count; i++){ if (grid.ActiveRow.Cells[i].IsTabStop) { grid.ActiveCell = grid.ActiveRow.Cells[0]; break; }}// Place into edit modegrid.PerformAction(Infragistics.Win.UltraWinGrid.UltraGridAction.EnterEditMode, false, false);}catch{ }}
Hi Todd,
I'm having some trouble understanding the situation. It's clear that you have some grids and Radio buttons on a scrollable form.
If you tab into a grid that is partially out of view, the form will scroll the grid control into view. This has nothing to do with the grid, the form does this. Three's a property on the form called AutoScroll which automatically tries to scroll the active control into view.
Todd N said:This makes the page extremely difficult to use if there is content present in these rows. If you reverse tab - or even repeatedly click between the two cells on a row and the form re-positions to the bottom the row you are clicking - till any rows that were visible (i.e. 3 valid rows that were visible below current row) - no longer are.
Here's where you lost me. This paragraph doesn't make sense. I think you are missing some words in there.
Can you post a small sample project demonstrating the issue you are having so we can check it out? I expect with something so complex, it will be impossible to assist you without a sample we can work with. There are just too many factors in play here.
(I really hate this forum editor - entered all the following, guess I typed too much - took so long I guess it timed out and page refreshed - gone, did it again - clicked preview - tried clicking video, got MS warning - clicked allow - page refreshed, gone again. third try...):
Hi Mike,
Sorry - the application is way too large for me to attempt and copy off enough to create a sample. What I did do though is copy some related code below, and capture a video of the described problem; showing the bottom with the Start button - and just a partial form so I could get in close to the grid. This is a very large form with numerous controls (textboxes, grids, drop-downs, etc. all with labels so 50 to 200 are likely added depending on form purpose), of which this section is a lot of grids, the grids are added dynamically from a parent class.
In the video I click the Yes box - then tab forward into a new box, entering 3 rows - using only the TAB key to manuver forward and backward through the grid - as you can see, going backward - as soon as I tab back from the 3rd row to the second row - the page re-scrolls to block the 3rd row from view. I go through the sequence a couple times - then you'll see the mouse - with 3 rows visible, I'll click the second row cell, then first row cells alternately - and with each click the page scrolls down until just the first row is visible - then I tried the column header - no surprise - now cannot even see the first row.
I did notice if I click yes and TAB into a barely visible grid - that as you said, the form scrolls to place 'almost' the entire box on the page, just a few pixels of the grid remain off the page. The problem is - IF the grid is remotely off the screen which it was here - the form scrolls on click. If the entire grid is visible, above the bottom of the form - then the form does not scroll at all.
This is not a show-stopper - the application can be used - but considering the users have been 'TAB'ing through these grids for years - since updating from 7.3 to 11.2 they now have to manually re-position the page at times to work on a medication table now - which is why it was sent to me.
Trivia: I did download the source for 11.2...2028 - and sorry, I forgot the line - but I found the auto-scroll function that was causing this to happen, commented it out and solve this - course, management didn't want modified 3rd party code so that solution/directory was deleted when the app was released in February.What was happening then was the following code - previously used with 7.3 - now used with 11.2 caused the entire page to scroll dramatically making it unusable - so OnGridEnter was commented out for the Feb release. Then it was realized that this code was what enabled TABing through cells - thus my fix above - redesign of this method. So - you could paste this in a sample grid app, attach it to the grid-event and see if it destroys scrolling in that app??
From the form related to Grid:
public static void OnGridEnter(object sender, EventArgs e) { UltraGrid grid = (UltraGrid)sender;
// Activate the first non-hidden cell. using (UltraGridColumn FirstNonHiddenColumn = grid.DisplayLayout.Bands[0].Columns.OfType<UltraGridColumn>().FirstOrDefault(a => !a.Hidden)) { if (FirstNonHiddenColumn != null) { grid.Rows.TemplateAddRow.Cells[FirstNonHiddenColumn.Index].Activate(); } }
grid.PerformAction(UltraGridAction.EnterEditMode); }
public static void BeforeGridRowDeactivate(object sender, System.ComponentModel.CancelEventArgs e) { UltraGrid grid = (UltraGrid)sender; int activeRowIndex = grid.ActiveRow.Index; grid.Rows[activeRowIndex].PerformAutoSize(); }
From the class that dynamically adds this grid to the form:
UltraGrid grid = new UltraGrid(); grid.Name = currentQuestion.Id.ToString(); grid.DisplayLayout.TabNavigation = TabNavigation.NextControlOnLastCell; grid.Leave += new System.EventHandler(QuestionnaireForm.OnGridLeave); grid.BeforeRowDeactivate += new System.ComponentModel.CancelEventHandler(QuestionnaireForm.BeforeGridRowDeactivate); grid.InitializeLayout += new Infragistics.Win.UltraWinGrid.InitializeLayoutEventHandler(QuestionnaireForm.OnInitializeLayout); // Enter - used during form load to pre-enable grids if they have data - normally all grids loaded disabled grid.Enter += new EventHandler(QuestionnaireForm.OnGridEnter); // AfterCellUpdate - sets values from database grid.AfterCellUpdate += new CellEventHandler(grid_AfterCellUpdate); grid.Error += new Infragistics.Win.UltraWinGrid.ErrorEventHandler(this.OnGridError); grid.DataSource = currentQuestion.GridResponses; grid.Top = currentQuestion.AnswerYCoordinate; grid.Left = currentQuestion.AnswerXCoordinate; grid.Height = currentQuestion.AnswerHeight; grid.Enabled = questionEnabled;
section.Controls.Add(grid);
There is further processing to set cell styles based on content - I exclued thatsince technically with breakpoints in it, they never hit on this form load. The calling class uses this grid for other forms as well which may use these set cell styles. This from uses only standard text cells.
I am unable to view the video you posted here. Looks like it requires a plug-in that I don't have.Maybe you could try going to the Options tab and simply attaching a file rather than embedding the video.If that doesn't work, maybe you could post step-by-step screen shots.
So, I'm still not really clear on what's happening.
What code did you comment out in the grid to 'fix' this?
You'll note two versions of OnGridEnter(..) - in my first original post is the working version - directly above is the version that worked in 7.3 that had to be commented out to avoid the page scrolling problems in 11.2.
The video works in IE, a standard .avi file - second time I tried to preview it I almost gave up too - it takes like 30 seconds to start... almost 6MB. I right-clicked and grabbed the shortcut - http://community.infragistics.com/cfs-file.ashx/__key/CommunityServer.Discussions.Components.Files/65/5875.med_2D00_box_2D00_video.avi so you know where it's at on your servers. This took like 15 seconds to start pasted directly in a browser. Auto-played in Windows Media player 12 in my Windows 7.
Tried attaching it - and got "The maximum file size allowed is 200kB. Please select a valid file." so I guess not. Maybe you can give it a few minutes to download, try a different browser or contact your managment and get it from the hosting server or get the attachment size raised so I can attach it.
I tried zipping it and got it to 475k - so if the limit was set to 500k I could attach it. 200kb is 100kb smaller than the .proj file in this application (300kb)... course, it has 10 other projects in it too, and is dB dependent to run.
Or you could get my email from the Forum - email me and I'll reply with it attached.
Okay, I downloaded the video and I can see it, now.
The video here doesn't show the form's scrollbars, but as I understand it, the the issue is that the form is scrolling as you tab between cells in the grid when the grid is partially out of view.
Is that right? I just want to make sure I am looking at the right problem.
If that is the case, and the problem does not occur when the grid is fully in view, then couldn't you work around this by always scrolling the grid completely into view in the grid's Enter event? I haven't tried it, but there must be some way to detect the current scroll position and bounds of the form and detect whether the grid is entirely in view or not, and then scroll it into view it's not.
Todd N said:You'll note two versions of OnGridEnter(..) - in my first original post is the working version - directly above is the version that worked in 7.3 that had to be commented out to avoid the page scrolling problems in 11.2.
I was asking what code in the grid's source you were referring to. There's nothing in the grid that scrolls the form or the container that the grid is in.
Anyway, I tried reproducing the issue and I cannot reproduce it. If I have a grid that is partially cut off on a scrollable form and I tab between cells, everything works fine for me. The form does not scroll.
I also tried using the same code you have for your OnGridEnter method. In this case, I do see a problem when I tab into the grid. It looks like this code is causing an infinite loop. When I call PerformAction(EnterEditMode), I end up getting back into the Enter event of the grid. This looks like a timing issue.The grid is apparently still in the middle of processing something when the Enter event fires.
I was able to get around this problem by moving the code form the Enter event into a method and calling it from the event handler via a BeginInvoke. That way the grid's processing completes before the call to PerformAction occurs:
private void ultraGrid1_Enter(object sender, EventArgs e) { UltraGrid grid = (UltraGrid)sender; grid.BeginInvoke(new MethodInvoker(this.EnterEditMode)); } private void EnterEditMode() { UltraGrid grid = this.ultraGrid1; UltraGridColumn FirstNonHiddenColumn = this.ultraGrid1.ActiveColScrollRegion.VisibleHeaders[0].Header.Column; if (FirstNonHiddenColumn != null) { grid.Rows.TemplateAddRow.Cells[FirstNonHiddenColumn].Activate(); } grid.PerformAction(UltraGridAction.EnterEditMode); }
Also... note that I changed how you are getting the first visible column. I'm not sure why your code is using a 'using' statement there, but it seems to me that if you do it like that, the column will get disposed as soon as they code block exits. So I don't see how that can possibly be working for you, unless the code you are using is somehow cloning the column.
Update: I did find the old project - had it on my VM WIndows XP environment.
The bad news - the source I found the bug in was 7.3.20073.1070 - I think I might have made up that # to get it to ignore the assembly build - in any case, it will not compile since updating to 11.2 and it's license is not registered. I get a 'The located assempbly's manifest definition does not match the asembly reference.' error.
The good news - it still has my breakpoint settings - and one is where I put it to fix the old scroll issue problem. It was in Utilities.cs on the method at line 4082:
// MD 11/7/06 - BR17484#region FocusControlWithoutScrollingIntoView/// <summary>/// Focuses a control without scrolling it into view if it is contained in a ScrollableControl. /// </summary>/// <param name="control">The control to focus.</param>/// <remarks>/// This will only work properly in CLR version 2.0 or later./// Otherwise, it will just focus the control./// </remarks>public static void FocusControlWithoutScrollingIntoView( Control control ){
return; // This is my fix - ignore the entire method
Point oldAutoScrollOffset = control.AutoScrollOffset;
try{
Point newOffset = control.Location;
// MBS 12/19/06 // Use safe parent accessors//Control parent = control.Parent;Control parent = GetParent(control);
// MBS 7/5/07 - BR23957// We only want to take non-default action when the control is wider and taller// than its immediate parent, otherwise we'll end up constantly shifting the control// by an incorrect offset.
if (parent != null && control.Height <= parent.Height && control.Width <= parent.Width &&
// MBS 9/24/08 - TFS6762// For the same reason as below, we only need to make this compensation when the parent// is set to AutoScrollparent is ScrollableControl && ((ScrollableControl)parent).AutoScroll){
FocusControl(control);
return;
}... rest you can find...
Hopefully that is enough for you to get a clue where I had the work-around before - So yes, this was called during the grid processing I think - cannot debug into it now so not sure how it got called - but without it the form worked normally. If you want to try and replicate it - use the OnGridEnter with the FirstNonHiddenColumn code - one you fixed - and maybe it will tell you something...
later, Todd
That method was specifically added to avoid problems where the grid would cause the parent window to scroll when tabbing through the cells.
The problem is that when you tab into a normal text cell in the grid, the grid displays a TextBox over the cell and the form scrolls the TextBox control into view, even if it's already in view and even if the entire grid is already in view.
So this code is intended to prevent that scrolling. So perhaps your workaround is somehow interfering with the workaround.
Anyway, I have sent a message to Infragistics Developer Support and they are going to create a case for you where you can attach a sample so we can take a look.