Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS Tech Support » Updating property grid Collapse All
Subject Author Date
David Skok Sep 11, 2007 - 8:54 AM

I have a question similar to thread: http://www.prof-uis.com/forum2.aspx?CID=40# regarding updating property cells.

I use a property grid in my application. I would like to include include read only items in some property sheets along side items that can be changed by the user. The read only items that I refer to are real time status such as counters and time values. I found if I change the property store then call PropertyStoreSynchronize() it reloads the grid as you indicated. I then tried to get at the "cloned" cells within the CExtPropertyGridWnd and cannot find them. I tried the following:

CExtPropertyGridControl *pPGC ... pointer to my grid control loaded with my property store

CExtPropertyGridWnd *pGW = pPGC->GetActiveGrid();

// A simplified example to show what I tried...

HTREEITEM htItem = pGW->ItemGetRoot();
htItem = pGW->ItemGetFirstChild( htItem );

// I assume that column 1 is the property data cell
CExtGridCell *pCell = pGW->ItemGetCell( htItem, 1, 0, 0, false, false );

pCell does not point to a cell of type that I use in the property store!! How can I get the address of the cell in the grid so that I can update it?

Technical Support Sep 11, 2007 - 10:56 AM

You are trying to get a grid cell which corresponds to some property value in the active tree grid only. But the property grid control typically contains more than one tree grid (two by default: categorized and sorted). Besides, it is not a good idea to use HTREEITEM based APIs because the tree structure can be changed during development after adding/removing property values and categories in the property store. So, we would recommend to use simpler and safer code like this:

CExtPropertyGridCtrl * pPGC = . . .
CExtPropertyValue * pPV = . . . // your counter or timer property value
CExtGridCell * pCellSrc = pPV->ValueActiveGet();
      ASSERT_VALID( pCellSrc );

// We assume your code has changed the active grid cell inside pPV
// (which is pCellSrc) here. This corresponds to the timer/counter
// changing action.

// In the case of timers and counters, you have reason to assign
// default value from active one. This will disable the Reset command
// in context menu for it. We guess timers and counters 
// should not be editable too:
      pCellSrc->ModifyStyle( __EGCS_READ_ONLY );
      pPV->ValueDefaultFromActive();

// Now time to update this property value in all pPGC:
CTypedPtrArray < CPtrArray, CExtPropertyGridWnd * > arrGrids;
      pPGC->OnPgcQueryGrids( arrGrids );
INT nGridIdx = 0;
      for( ; nGridIdx < arrGrids.GetSize(); nGridIdx ++ )
      {
            CExtPropertyGridWnd * pGrid = arrGrids[ nGridIdx ];
            ASSERT_VALID( pGrid );
            // Get HTREEITEM handle which corresponds to
            // the pPV property value:
            HTREEITEM hTreeItem = pGrid->PropertyItemToTreeItem( pPV );
            if( hTreeItem == NULL )
                  continue;
            // Get the destination grid cell which is cloned from
            // the active cell of the pPV property value:
            CExtGridCell * pCellDst = pGrid->ItemGetCell( hTreeItem, 1 );
            if( pCellDst == NULL )
                  continue;
            ASSERT_VALID( pCellDst );
            // Update destination grid cell’s value:
            pCellDst->Assign( *pCellSrc );
            // Repaint required part of the tree grid:
            if( ! pGrid->IsWindowVisible() )
                  continue;
            LONG nRowNo = pGrid->ItemGetVisibleIndexOf( hTreeItem );
            if( nRowNo < 0 )
                  continue;
            CRect rc;
            if(   pGrid->GridCellRectsGet(
                        1,
                        nRowNo,
                        0,
                        0,
                        NULL,
                        &rc
                        )
                  )
            {
                  CRect rcClient;
                  pGrid->GetClientRect( &rcClient );
                  rc.left = rcClient.left;
                  rc.right = rcClient.right;
                  pGrid->InvalidateRect( &rc );
            }
      }


David Skok Sep 11, 2007 - 1:15 PM

Thank you, this is exactly what I was looking for.

You were correct in assuming that timers/counter cells should be read only. I have found that despite setting them to __EGCS_READ_ONLY the inplace editor is still invoked when the property value is selected and clicked. It is not possible to enter text or numbers however you can use left and right cursor keys to move the cursor and use delete key to remove characters. I assume this is a bug. This behavior is also exhibited in the PropertyGrid sample as follows: Start the PropertyGrid sample. Display the properties of a single button. Scroll down to the Handle property which is supposed to be read only. Do a left mouse click on the Handle property value. Notice that the inplace editor is created. Use the left arrow key to move the cursor into the handle value. Press the delete key to remove some characters. Press enter to accept the value.

Technical Support Sep 11, 2007 - 1:44 PM

The editing of the read-only cell problem is fixed in the latest source code you can request by email. The read-only cells have in-place editor, but it must be read-only too. You can disable in-place editor activation using the following code:

      pCellSrc->ModifyStyle( __EGCS_NO_INPLACE_CONTROL );
or, in the case of your timers and counters:
      pCellSrc->ModifyStyle( __EGCS_READ_ONLY | __EGCS_NO_INPLACE_CONTROL );