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 General Discussion » Questions about Property Grid Collapse All
Subject Author Date
Soo Wei Tan Dec 12, 2006 - 1:32 PM

I’m trying to implement a property grid in a MDI application with Document/View architecture and I have a couple of questions. I want to place a CExtPropertyGridCtrl as part of the MainFrame. So far it looks like I have to place it in a CExtControlBar (which is already implemented, but it currently contains a CListBox which the property grid is to replace).

My questions are:
From a design perspective, do I place the property store in the document? The property grid needs to be updated frequently (2-3 times/second). The way I have the CListBox setup right now is to run a timer in the MainFrame and grab information from the document and update it when the timer fires. Would a similar implementation do the same for the property grid?

In addition, in order to to change the values of the properties, the easiest way would be to create getters and setters for each and every property?

Thanks!

Soo Wei Tan Dec 18, 2006 - 10:05 AM

Excellent information, thank you!

Technical Support Dec 15, 2006 - 5:27 AM

You can use the property grid instead of the list box template without any problems. Here are the details related to your questions:

1) The CExtPropertyGridCtrl window keeps only a reference to an externally instantiated CExtPropertyStore property store and it never deletes the property store. So, you can keep one or more property stores in the document. If your document is about to be destroyed and it is about to destroy the property store in it, you should check if this property store is currently attached to the property grid control:

CExtPropertyGridCtrl * pPGC = ...
CExtPropertyStore * pDocPS = ...
if( pPGC->PropertyStoreGet() == pDocPS )
    pPGC->PropertyStoreSet( NULL );
delete pDocPS;
2) In MDI child frames, you should handle the activation event so that you can assign the document’s property store to the property grid control.

3) As for the question about the property grid control that is frequently updated, as the first step you simply have to modify the grid cells (the active grid cells, not the default ones) of property values inside the document’s property store and then update the property grid control:
CExtPropertyGridCtrl * pPGC = ...
CExtPropertyStore * pDocPS = ...
//
// ... modify property values ...
//
if( pPGC->PropertyStoreGet() == pDocPS )
{
    pPGC->SetRedraw( FALSE );
    pPGC->PropertyStoreSynchronize();
    pPGC->SetRedraw( TRUE );
    pPGC->RedrawWindow( NULL, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN );
}
This code completely rebuilds the content of the property grid. But this is not the best solution. The better approach would be to update only those property values that were changed:
  
CExtPropertyGridCtrl * pPGC = ...
CExtPropertyValue * pSomePropertyValue = ...
CExtGridCell * pCellSrc = pSomePropertyValue->ValueActiveGet();
// 
// ... modify the data stored in the pCellSrc grid cell ...
//
CTypedPtrArray < CPtrArray, CExtPropertyGridWnd * > arrGrids;
pPGC->OnPgcQueryGrids( arrGrids );
INT nGridIdx;
for( nGridIdx = 0; nGridIdx < arrGrids.GetSize(); nGridIdx ++ )
{
    CExtPropertyGridWnd * pWndTreeGrid = arrGrids[ nGridIdx ];
    ASSERT_VALID( pWndTreeGrid );
    HTREEITEM hTreeItem = pWndTreeGrid->PropertyItemToTreeItem( pSomePropertyValue );
    if( hTreeItem == NULL )
        continue;
    CExtGridCell * pCellDst = pWndTreeGrid->ItemGetCell( hTreeItem, 1 );
    if( pCellDst == NULL )
        continue;
    ASSERT_VALID( pCellDst );
    pCellDst->Assign( *pCellSrc );
    bool bGridIsVisible = ( (pWndTreeGrid->GetStyle()&WS_VISIBLE) != 0 ) ? true : false;
    if( ! bGridIsVisible )
        continue;
    LONG nRowNo = pWndTreeGrid->ItemGetVisibleIndexOf( hTreeItem );
    if( nRowNo < 0 )
        continue;
    CRect rcCellExtra;
    if( ! pWndTreeGrid->GridCellRectsGet( 1, nRowNo, 0, 0, NULL, &rcCellExtra ) )
        continue;
    pWndTreeGrid->InvalidateRect( &rcCellExtra );
    pWndTreeGrid->UpdateWindow(); // optional (to see the changes immediately)
}