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)
}