HOME | SIGN UP | ACCOUNT | SUBSCRIBE | STORE | WHAT'S NEW | TESTIMONIALS | TROUBLESHOOTING | SUPPORT AREA | SITE NEWS | LOGIN
Classes & methods · News · Jobs · Links · Downloads · Articles · Conferences · Magazines · Training · Consultants · Consulting · Blogs · FAQ
Books · Applications · Meetings · User groups · Speakers · User group leaders · Universal Thread Magazine · Coverages · Photos · Videos

 ID: 8151Created on: February 8, 2002 08:39Updated on: April 22, 2010 21:31

How to freeze (lock) a column in the grid without use of split bar
Summary:The approach is based on a simple principle. LeftColumn property of the grid represents a column that is currently the leftmost visible column in the grid with current horizontal scrolling. As we scroll the grid horizontally, this property changes. We can assign this number to the ColumnOrder property of the column we want to hold and that’s all:
this.Columns(1).ColumnOrder = this.LeftColumn 
You can use this in the Scrolled and AfterRowColChange events of the grid. However, there is a little problem with this: order of columns spoiled after few scrolling forward and back. This is because column order changes using principle "replace older column by newer on that place", so older column is placed on place of newer column. Column orders of all other columns are not changed. This causes the problem. This FAQ describes an approach that allows to organize freezing of the column and workaround most issues. The code is a very basic and simple to give the basics of the approach. Code samples could be improved to work correctly in case user change order of columns, as well as improve the logic related to the focus change.
Rating: Rate this entry
Created by:
Vlad Grynchyshyn
Soft Serve
Lviv

Following is a code that updates columns in grid to make first column always leftmost. Use it in the Scrolled event when grid is scrolled horizontally and in the AfterRowColChange event when active column is changed in the grid.

	local i
	if this.columns(1).ColumnOrder < this.LeftColumn
		&& we scroll forward
		for i=this.columns(1).ColumnOrder to this.LeftColumn-1
			this.columns(1).ColumnOrder = this.columns(1).ColumnOrder + 1
		endfor
	else
		&& we scroll backward
		for i=this.LeftColumn+1 to this.columns(1).ColumnOrder
			this.columns(1).ColumnOrder = this.columns(1).ColumnOrder - 1
		endfor
	endif


The above code is very simple because it is written only for the column 1 and only one column frozen. The approach change ColumnOrder of the column by 1. This cause correct moving of column to required place like if you move the column by dragging it by header. This save the original order of columns and solve any problems with confusing order change after scrolling. Use this code in the AfterRowColChange event (when column changed) or in the Scrolled event (when grid is scrolled horizontally, in other words, when nDirection parameter of the Scrolled event is greater or equal 4).

For more complex case (more than one column) you will require to do similar things. For example, following is for 2 columns:

	local i, lnCurrOrder
	m.lnCurrOrder = this.columns(1).ColumnOrder
	if this.columns(1).ColumnOrder < this.LeftColumn
		&& we scroll forward
		for i=m.lnCurrOrder to this.LeftColumn-1
			this.columns(2).ColumnOrder = this.columns(2).ColumnOrder + 1
		endfor
		for i=m.lnCurrOrder to this.LeftColumn-1
			this.columns(1).ColumnOrder = this.columns(1).ColumnOrder + 1
		endfor
	else
		&& we scroll backward
		for i=this.LeftColumn+1 to m.lnCurrOrder
			this.columns(1).ColumnOrder = this.columns(1).ColumnOrder - 1
		endfor
		for i=this.LeftColumn+1 to m.lnCurrOrder
			this.columns(2).ColumnOrder = this.columns(2).ColumnOrder - 1
		endfor
	endif



Finally, when doing manipulations with column objects on the form, the current focused column might be lost. The workaround for this is to remember current focused column and set the focus back after moving "locked" columns. So, wrap the column(s) moving code (above sample code) into the following code:

	lnCol = this.ActiveColumn
	lnColToFocus = 0
	if lnCol > 0
		for i=1 to this.ColumnCount
			if this.columns(m.i).ColumnOrder = m.lnCol
				lnColToFocus = m.i
				exit
			endif
		endfor
	endif

        * Check if we do not need to set focus to the last column in grid
        * This will happen when we did not focused column explicitly by 
        * mouse and pressed either Shift+TAB, left arrow key or Ctrl+left 
        * arrow key. In the last condition we check if column focused is 
        * the locked column. When you have 2 columns, you should check for 
        * both (for example, 
        * "AND (m.lnColToFocus = 1 OR m.lnColToFocus = 2)")
	if not MDOWN() AND inlist(lastkey(),15,19,26) AND (m.lnColToFocus = 1)
			this.Columns(this.ColumnCount).SetFocus
			m.lnColToFocus = this.ColumnCount
	endif

* ....... Put here code from previous samples

	if lnColToFocus > 0
		if this.Columns(m.lnColToFocus).ColumnOrder > this.LeftColumn
			this.Columns(m.lnColToFocus).SetFocus
		else
			* Determine the next column after locked and focus it
			for i=1 to this.ColumnCount
				if this.columns(m.i).ColumnOrder = this.Columns(1).ColumnOrder + 2
					lnColToFocus = m.i
					exit
				endif
			endfor
			this.Columns(m.lnColToFocus).SetFocus
		endif
	endif


The side effect of the above code is that "TAB" key pressing in last column when it is active will cause moving to the first column that is not locked. This is a good thing also, because usually locked column is used as information column when others are for data entry. To do opposite (SHIFT+TAB in the first not locked column will focus the last column), we should add some code in the AfterRowColChange event to fix the active column - appropriate section of the code in above sample is marked by comment "Check if we do not need to set focus to the last column in grid".

There is also a problem - when scrolling horizontally and focused column goes out of scrolled area, we just cannot restore active column because this will scroll the grid back. In such case it is good idea to set the focus to the column just after locked column(s) in current scrolling. This column will have next ColumnOrder value after the locked column. This workaround is after the comment "Determine the next column after locked and focus it".

Comments
Add a comment

More entries from this member

  1. 256-color icons in EXE application compiled by VFP May 28, 2002
    VFP does not support 256-color icons as project's icon (icon displayed for EXE in Windows Explorer). But 16-color icons usually looks ugly and too simplified. Here is an approach that allows organize 256-color icons for VFP EXE application. The approach is based on use of Resource Hacker application. You can download it from following URL: http://download.techworld.cz/software/resourcehacker.zip (UPDATED: original link does not work for some reason. Let me know if this one also does not ...

  2. Force positioning of text cursor by right mouse click in EditBox and RTF ActiveX controls February 8, 2002
    There is a situation often when we need some way to position a text cursor in the text of Editbox or RTF ActiveX controlwhen right click on the control. For example, we want to display a shortcut menu on right click. In menu, user select an option that insert some text into the control on place of current position. However, right click on the control does not change the text cursor position, that confuse users. It would be good to right click, cursor moves to the clicked point and then menu disp...

  3. Grid reconstruction and how to avoid it March 16, 2001
    Have you ever found a situation when your grid don't want to behave as you directed in design time? Custom controls in columns lost? Code of columns, headers or controls event not running? Read this FAQ then. Grid reconstruction behavior is a complete removing of all grid's controls and columns and creating them again using default VFP controls. This cause lose of all methods, property settings and objects in columns and all column objects, column control to display and edit data is reset to ...

  4. How to assign code to event in run-time? September 21, 2001
    In VFP there are no direct way to assign code to the method or event in run-time mode. However, some workaround is possible with use of additional, 'hook' class. The sample below describes the approach. It is possible to make it generic. The approach is very useful to catch, for example, events of the _Screen form.

  5. How to display Tool Tips for different parts of the Grid? February 1, 2002
    In VFP6 Grid value of the ToolTipText property of controls is displayed only for the entire grid or for current control when mouse is over it. Becuase there are a lot of parts in the grid, it is often useful to display tool tip for different parts separately. Unfortunately, VFP interprets grid as a single control, displayed tool tip appearance for grid is not changed immediately even when ToolTipText property is changed, until mouse is moved out of the grid and returned into the grid into requir...

  6. How to get form caption font properties October 6, 2000
    Windows form caption properties stored in the user preferences. You can change them using Windows Control Panel\Display\Appearance. To get these parameters programmatically in VFP, you can use following routine as a sample.

  7. How to make a collection property of VFP object February 6, 2001
    After some investigation, I managed to make a collection-like property of object. The following is a simple sample of how to organize collection-like access (rough, need to improve it to work as real collection). It is just to show an approach.

  8. How to make a grid appear like a list similar to list box June 20, 2001
    This article describes how to configure grid to appear as a list similar to the list box or the drop-down list of combo box. It is for appearance only. All other things are as usual for any grid. This is useful for case when need to replace list box by a grid to display more records, because listbox is slow when displaying 1000+ rows in listbox.

  9. How to make SQL Pass-Through cursor updatable April 9, 2002
    The SQLEXEC() function in VFP allows downloading of data from any data source through ODBC. Unlike remote views, SQL Pass-Through approach does not provide default (automatic) settings in the returned cursor to update data on the server after changes in the cursor at the client side. Anyway, it is possible to customize required properties to organize updating. First of all, it is recommended to read chapters about SQL Pass Through commands in the MSDN, specially, chapters that explain propert...

  10. How to organize SUM() for character field in SQL Server SELECT query September 4, 2001
    There is a little problem for query to get something like a sum() for a character field to concatenate character values from all records in the group. Here is described solution. The approach below have an limitation to max 30 records in group for concatenation. Test it if it will work for more records in group or there should be another limitation on your server, becaus ethis number is depended on SQL Server capabilities and length of the character field being concatenated.

  11. How to put grid on the form programmatically February 5, 2001
    Suggest Grid1 is a name of grid required to put onto the form, grid should contain 10 columns an display data from the MyAlias alias. Grid should contain a combo box in the second colunm with the name Combo1. Following sample routine will allow you to see a generic idea of how to put grid on the form programmatically and recreate it again when needed. You can make it as a custom method of the form and call it when needed (for example, thisform.MakeGrid or thisform.RefreshGrid).

  12. How to refresh grid properly after sorting January 26, 2001
    I have seen many questions about sorting of a grid by clicking on its header and proper refreshing of grid after sorting. There is a reliable way to sort (index) grid cursor and properly refresh the grid without change of the record number AND with very good looking. I made this in my grid class and tested it already 2 years so far.

  13. How to work with Image field type on SQL Server (binary data)? January 11, 2001
    Text field on SQL Serevr is not good to store binary data because it is not reliable and often SQL Server corrupts binary data in text field. varbinary type could be too short. There are certain difficulties to use image field on SQL Server to store and read binary data in VFP. Image field on SQL Server mapped to general field in VFP by default, causing some difficulties when using SQL Pass Through functions. The workaround idea is to try to use memo field to update data on SQL server. At ...

  14. SPT cursor fetching and progress displaying for SPT cursor downloading February 5, 2002
    SQL Pass Through commands often can take a lot of time for running and returning the result set to the client. It is often usefult to show a progress bar in case of such lengthy process. Also, FetchAsNeeded option, available for views, could be very useful for SPT cursors as well. However, how we can open SPT cursor and set FetchAsNeeded option for it? Here is a sample code for opening the cursor in "FetchAsNeeded" mode, as well as a description of approach for organizing the progress bar for...

Great Lakes Great Database Workshop 2002
DateContentDetail
08/09 17:50NewsSouthwest Fox Speaker Ch...
06/09 16:31MeetingSQL Server Tools, Strate...
02/09 00:44NewsPEM Editor 6 has been re...
27/08 17:57NewsSouthwest Fox 2010 Early...
25/08 04:30NewsCryptoLicensing For .Net...
22/08 09:58NewsWindows Phone 7 Gold Rush
16/08 03:05NewsVisual WebGui reveals it...
11/08 17:54MeetingSo You Think You Want To...
10/08 16:41News.NET Training for VFP Pr...
09/08 18:33MeetingLINQ & SQL Server Reporting
03/08 08:15JobsSQL/VFP Developer for Ma...
29/07 10:59News.NET 4 for VFP Developer...
26/07 10:13JobsVFP Developer (Two Perma...
25/07 06:44NewsWith Visual WebGui 6.4 R...
24/07 11:00JobsQuality Assurance Softwa...

Copyright © 1993 - 2010 Level Extreme Inc., All Rights Reserved · Telephone: 506-783-9007 Email: info@universalthread.com · Privacy & Security · Copyright · Terms & Conditions