Easy Navigation Through an Editable List View

First off, I would like to acknowledge that most of this code came from others at Code Guru. I took code from some of the articles submitted by Zafir Anjum, so look at his article "Editable Subitems" as a basis for this article.

This project demonstrates how the list view/control can be used to edit information in the form of a table (multiple-editable columns). I have captured the Tab, Page Down, Page Up, Up, Down, Home, and End keys to allow easy navigation through the control.

As shown in "Editable Subitems", I subclassed the CEdit control with my class called gxEditCell. Then, I added a new parameter to it's constructor. This new parameter is a pointer to the parent list control so that my edit box could inform the list control of any important events, like a key press. Then when I get a key event, I simply tell the list control which subitem I want to edit next based off the current cell that is being edited. This can be seen in the OnKeyDown function below. As you can see, when I receive the VK_UP key event, I am telling the list control to edit the subitem located directly above the current cell. I check, of course, to see if it is a valid cell first.

The reason I caught some events in the KeyDown, some in the KeyUp, and some in the OnChar, had to do with how the application behaved. If I would have caught the VK_PRIOR or VK_NEXT in the OnKeyDown, I would get several calls depending on how long the button was pressed. This is very annoying. If you don't believe me, move the code, add several items to the list and try it (it isn't pretty).

I also caught the ESC key so that I could cancel an edit. The return key is being used to end an edit and when it is on the last record, it insert a new one. Just don't forget to override the OnGetDlgCode() so that you can get the arrow keys and tabs.



gxEditCell::gxEditCell (gxListCtrl* pCtrl, int iItem, int iSubItem, CString sInitText)
:   bEscape (FALSE)
{
    pListCtrl = pCtrl;
    Item = iItem;
    SubItem = iSubItem;
    InitText = sInitText;
}

void 
gxEditCell::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) 
{
    // Up and down are in the OnKeyDown so that the user can hold down the arrow
    // keys to scroll through the entries.
    BOOL Control = GetKeyState (VK_CONTROL) < 0;
    switch (nChar)
    {
		case VK_UP :
		{
			if (Item > 0)
				pListCtrl->EditSubItem (Item - 1, SubItem);
			return;
		}
		case VK_DOWN :
		{
			pListCtrl->EditSubItem (Item + 1, SubItem);
			return;
		}
		case VK_HOME :
		{
			if (!Control)
				break;

			pListCtrl->EditSubItem (0, SubItem);
			return;
		}
		case VK_END :
		{
			if (!Control)
				break;

			int Count = pListCtrl->GetItemCount() - 1;
			pListCtrl->EditSubItem (Count, SubItem);
			return;
		}
    }
    
    CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
}

void 
gxEditCell::OnKeyUp (UINT nChar, UINT nRepCnt, UINT nFlags) 
{
    switch (nChar)
    {
		case VK_NEXT :
		{
			int Count = pListCtrl->GetItemCount();
			int NewItem = Item + pListCtrl->GetCountPerPage();
			if (Count > NewItem)
				pListCtrl->EditSubItem (NewItem, SubItem);
			else
				pListCtrl->EditSubItem (Count - 1, SubItem);
			return;
		}
		case VK_PRIOR :
		{
			int NewItem = Item - pListCtrl->GetCountPerPage();
			if (NewItem > 0)
				pListCtrl->EditSubItem (NewItem, SubItem);
			else
				pListCtrl->EditSubItem (0, SubItem);
			return;
		}
    }
    
    CEdit::OnKeyUp (nChar, nRepCnt, nFlags);
}

void 
gxEditCell::OnChar (UINT nChar, UINT nRepCnt, UINT nFlags) 
{
    BOOL Shift = GetKeyState (VK_SHIFT) < 0;
    switch (nChar)
    {
		case VK_ESCAPE :
		{
			if (nChar == VK_ESCAPE)
				bEscape = TRUE;
			GetParent()->SetFocus();
			return;
		}
		case VK_RETURN :
		{
			SetListText();
			pListCtrl->EditSubItem (Item + 1, 0);
			return;
		}
		case VK_TAB :
		{
			if (Shift)
			{
				if (SubItem > 0)
					pListCtrl->EditSubItem (Item, SubItem - 1);
				else
				{
					if (Item > 0)
						pListCtrl->EditSubItem (Item - 1, 2);
				}
			}
			else
			{
				if (SubItem < 2)
					pListCtrl->EditSubItem (Item, SubItem + 1);
				else
					pListCtrl->EditSubItem (Item + 1, 0);
			}
			return;
		}
    }

    CEdit::OnChar (nChar, nRepCnt, nFlags);

    // Resize edit control if needed

    // Get text extent
    CString Text;

    GetWindowText (Text);
    CWindowDC DC (this);
    CFont *pFont = GetParent()->GetFont();
    CFont *pFontDC = DC.SelectObject (pFont);
    CSize Size = DC.GetTextExtent (Text);
    DC.SelectObject (pFontDC);
    Size.cx += 5;			   	// add some extra buffer

    // Get client rect
    CRect Rect, ParentRect;
    GetClientRect (&Rect);
    GetParent()->GetClientRect (&ParentRect);

    // Transform rect to parent coordinates
    ClientToScreen (&Rect);
    GetParent()->ScreenToClient (&Rect);

    // Check whether control needs to be resized and whether there is space to grow
    if (Size.cx > Rect.Width())
    {
		if (Size.cx + Rect.left < ParentRect.right )
			Rect.right = Rect.left + Size.cx;
		else
			Rect.right = ParentRect.right;
		MoveWindow (&Rect);
    }
}

UINT 
gxEditCell::OnGetDlgCode() 
{
    return CEdit::OnGetDlgCode() | DLGC_WANTARROWS | DLGC_WANTTAB;
}

Download demo application - 11 KB

History



Comments

  • Organization Gossip : chanel Thought of as A Must In modern times

    Posted by incockDak on 03/29/2013 08:03am

    The Actual Key On the way to rule the longchamp-arena Is Quite Straight forward! [url=http://growth-management.alachua.fl.us/comprehensive_planning/gucci.html]バック[/url] The Secret dominate the gucci-world Is Fairly Basic! [url=http://growth-management.alachua.fl.us/comprehensive_planning/saclongchamp.php]Sac longchamps[/url] EbrNssYcrDuu [url=http://running-nike0.seesaa.net/]ナイキ[/url]SdsAdkZmkXov [[url=http://free-nike-nikeo.seesaa.net/]free nike[/url]WviIftBniMps [url=http://xn--nike-ul4c5c5fyqb.seesaa.net/]ナイキスニーカー[/url]RbqNgfYflRuw [url=http://nikejapan0.seesaa.net/]ナイキスニーカー[/url]JdwKcwWgpKpt [url=http://nikesneakersjp.seesaa.net/]nike[/url]EvnDqyEjyZvp [url=http://nikegolf00.seesaa.net/]ナイキゴルフ[/url]ZoeBrkAbgTbt [url=http://nikeshoes00.seesaa.net/]nike シューズ[/url]AaoHleJpbPla [url=http://sneaker-adidas-jp.seesaa.net/]スニーカー adidas[/url]KidSxwArgAui

    Reply
  • The most important bvlgari purse Company Dialog - Who loves pretty much nothing triumphs??

    Posted by expopmerm on 03/22/2013 08:29pm

    [url=http://www.mcmoutletjpinoue.com]mcm 店舗[/url] mcm Offers Fresh, New Life For An Old Topic- Defacto Requirements [url=http://www.mcmsalejapanoka.com]MCM 財布[/url] Stimulating Actions All mcm Admirer Really Should Try Out [url=http://www.mcmzankijpshop.com]mcm バッグ[/url] The Way To Stay Away From mcm Mishaps [url=http://www.mcmstorejpkodo.com]MCM 財布[/url] mcm Imitations . . . Ideal mcm Hack Which Fools 98% Of The Customers Reliable guidelines for bvlgari purse that can be used beginning straight away. [url=http://www.bvlgarishopjprie.com]ブルガリ 時計[/url] The fundamental principles of the bvlgari purse that you'll take advantage of getting started today. [url=http://www.bvlgarioutletshopjp.com]ブルガリブルガリ[/url] Howdy! Together we are able to help make bvlgari purse considerably better ! [url=http://www.bvlgarisalekodojp.com]ブルガリ[/url] Summary write-up reveal the unquestionable details about bvlgari purse and also the way it could may affect people. [url=http://www.bvlgarisakaijpsale.com]ブルガリ 財布[/url] Fresh site exposes the low down around bvlgari purse and as well , reasons why need to take action straight away. [url=http://www.bvlgariaokisalejp.com]ブルガリイルカフェ[/url] Current market Report : bvlgari purse Defined as A-must At this time End Up Being The 1st To Read What The Researchers Are Saying Around [url=http://www.mcmbagsjphadori.com]MCM 店舗[/url] Probably The Most Unnoticed Detail Around mcm

    Reply
  • Source code

    Posted by Legacy on 10/01/2003 12:00am

    Originally posted by: kripa

    Lee !!!! can i have the source code of the editable list view??

    • jkj

      Posted by huahuajin on 03/18/2008 10:24am

      dsfs

      Reply
    Reply
  • One more fix to correct mouse wheel behavior...

    Posted by Legacy on 09/02/2003 12:00am

    Originally posted by: Chang

    The default OnMouseWheel(), derived from CWin, does not work well. Should be handled similar to OnHScroll or OnVScroll in gxListCtrl.
    
    

    Simply adding the following handler should be enough.

    BOOL gxListCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
    {
    if (GetFocus() != this)
    SetFocus();

    return CListCtrl::OnMouseWheel (nFlags, zDelta, pt);
    }

    ...and I assume you won't forget to add ON_WM_MOUSEWHEEL() to the message map.

    Reply
  • Handling arrows and tab in modeless dialog box?

    Posted by Legacy on 01/08/2003 12:00am

    Originally posted by: Eric Lepage

    Hello,

    This code sample is fabulous. I've been able to reproduce a spreadsheet-like behavior!!!

    It works great in modal dialog box but modeless dialogs won't get the arrow and tab keys. I've tried catching them thru OnGetDlgCode() with no success.

    Anyone has a suggestion?

    Thanks!

    Reply
  • Good but

    Posted by Legacy on 07/09/2002 12:00am

    Originally posted by: How to add columns?

    1) I could able to add columns. bu when navigation the focus is not reaching on to new columns.
    
    what i have to do for it.

    2) the other question is when the first cell loses the focus i want to fire a query depending on the first cell's value how can i do it?

    3) How to make it on CFormView?

    Reply
  • Invalid handling of the ESC

    Posted by Legacy on 12/11/2001 12:00am

    Originally posted by: Stephane Stolz

    The ESC is not properly handled.
    In this implementation, the assumption made is that the edit will be cancelled only when the ESC key is pressed.
    The correct way of handling the changes is to cancel the edit for as long as the text was not changed.

    I have modified the code in the following way to fix this:
    1. In the constructor, set the Escape to TRUE by default.
    2. In OnChar, add a default in the switch statement to set the Escape to FALSE as soon as the user changes the value.

    This makes a huge difference if you use this ListCtrl to edit a database. As you navigate through the columns, the database would be updated even though no value was changed.
    By adding the above changes, the database will be update only when something was changed.

    Other than that, this code is very useful.
    Thanks a lot.

    Reply
  • I need to do the same but with list controls

    Posted by Legacy on 08/14/2001 12:00am

    Originally posted by: Nuno Rapaz

    How can i do the same in list controls?

    Reply
  • Good But.....

    Posted by Legacy on 07/31/2001 12:00am

    Originally posted by: Guru

    Hi,
    I ahve used in this my current project.
    It is good.

    But I ahve small problem.

    For the second and 3rd cols I want to edit.
    But the edit control should specify / allow only some particular characters.

    Rest it should not accept.

    When I tried to do the same by mapping EditCell's OnUpdate, it is throwing Application Error stating that m_hWnd == NULL.

    Pls help me.

    Regds

    Reply
  • I don't know....

    Posted by Legacy on 04/15/2001 12:00am

    Originally posted by: Dark

    First...
    Thanks for your sample project.
    It's very useful sample..
    Anyway....
    I make Dialog Box, and put a List Box in it.
    I want to use a member function in the List View, when the List Box is double clickked.
    I don'w know how....
    How can I do?

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • IBM Worklight is a mobile application development platform that lets you extend your business to mobile devices. It is designed to provide an open, comprehensive platform to build, run and manage HTML5, hybrid and native mobile apps.

  • Agile methodologies give development and test teams the ability to build software at a faster rate than ever before. Combining DevOps with hybrid cloud architectures give teams not just the principles, but also the technology necessary to achieve their goals. By combining hybrid cloud and DevOps: IT departments maintain control, visibility, and security Dev/test teams remain agile and collaborative Organizational barriers are broken down Innovation and automation can thrive Download this white paper to …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds