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 » Problems with the synchronization of CExtPropertyGridCtrl Collapse All
Subject Author Date
Andreas Werner Nov 30, 2006 - 9:38 AM

Dear support team,

I am using a CExtPropertyGridCtrl with about 60 property items in about 12 categories. The property items have dependencies, i.e. if for example the checkbox item X is not checked, then the colour items A, B and C have to be read only.
I implemented this behaviour in the following way:

I wrote a class derived from CExtPropertyValue for the checkbox item. I overwrote the Apply method this way:

    CExtPropertyValue::Apply(pValue);

    CExtGridCellBool * pValueBool =
        static_cast<CExtGridCellBool*>(pValue);
    bool newValue = pValueBool->DataGet ();
    
// For each dependent item
    CExtGridCell * cell = dependentItem->ValueActiveGet();

    if (newValue == TRUE)
    {
        // if checkbox checked -> remove style __EGCS_READ_ONLY
        cell->ModifyStyle (0L, __EGCS_READ_ONLY);
    }
    else
    {
        // if checkbox not checked -> add style __EGCS_READ_ONLY
        cell->ModifyStyle (__EGCS_READ_ONLY, 0L);
    }
// For each dependent item end


// Synchronize the property grid to apply the changes
    m_ptrPGC->SetRedraw( FALSE );
m_ptrPGC->PropertyStoreSynchronize();
m_ptrPGC->SetRedraw( TRUE );
    m_ptrPGC->RedrawWindow( NULL, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN );


When I click the checkbox of the property item I get the following result:
The application takes a noticeable break.
The grid window scrolls to the middle position.
The checkbox of the property item gets painted according to its now state
The dependent items change from read only to read write or vice versa according to the new state.

How can I prevent the property grid window from scrolling to the middle after the synchronization with the property store? I would like it to remain in its scroll position.

The call off PropertyStoreSynchronize causes a noticeable delay in the application. It seems that the whole property store is synchronized with the property grid. Is there another way to apply the new state (RW or RO) of the dependent items to the property grid?

With best regards Andreas Werner

Suhai Gyorgy Dec 1, 2006 - 2:36 AM

I can only say sure about the scrolling issue. PropertyStoreSynchronize removes all cells from every grid window and inserts them again. This means that the last category will be the focused cell after the synchronization. You have to set the focus back to the cell that was changed last. That will solve the scrolling problem.

	CExtPropertyGridWnd * pActiveGrid = m_ptrPGC->GetActiveGrid();
	CExtPropertyItem *pFocusedItem = pActiveGrid->PropertyItemFromTreeItem(pActiveGrid->ItemFocusGet());
	m_ptrPGC->SetRedraw( FALSE );
	m_ptrPGC->PropertyStoreSynchronize();
	HTREEITEM hTreeItem = pActiveGrid->PropertyItemToTreeItem( pFocusedItem );
	pActiveGrid->ItemFocusSet( hTreeItem );
	m_ptrPGC->SetRedraw( TRUE );
	m_ptrPGC->RedrawWindow( NULL, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN );
Although CExtPropertyGridWnd has a PropertyStoreSynchronizeOneLevel method, it wants to insert the PropertyItem given as parameter, and asserts if finds the propertyitem already in the grid. So I’m not sure about how to solve your other problem.

Technical Support Dec 1, 2006 - 7:23 AM

In addition to what Chris advised, we would like to add the following. The CExtPropertyGridCtrl::PropertyStoreSynchronize() method completely rebuilds the contents of all tree grids inside the property grid control. You should not use this method in your implementation of dependent property values. Use direct access to the tree grids instead. Please note that a property value inside the property store keeps two grid cell objects corresponding to the initial and current satets of the value. Each tree grid contains only one copy of the current (active) cell for each propery value. For example you have some property value in the property store:

CExtPropertyGridCtrl & _PGC = . . .
CExtPropertyValue * pPropertyValue = . . .
CExtGridCellBool * pValueBool = STATIC_DOWNCAST( CExtGridCellBool, pPropertyValue->ValueActiveGet() );
bool newValue = pValueBool->DataGet();
. . .
The code below will assign all copies of pValueBool grid cell in all tree grids inside the property grid control:
CTypedPtrArray < CPtrArray, CExtPropertyGridWnd * > arrGrids;
    _PGC.OnPgcQueryGrids( arrGrids );
INT nGridIdx = 0, nGridCount = INT( arrGrids.GetSize() );
    for( ; nGridIdx < nGridCount; nGridIdx ++ )
    {
        CExtPropertyGridWnd * pGrid = arrGrids[ nGridIdx ];
        ASSERT_VALID( pGrid );
        HTREEITEM hTreeItem = pGrid->PropertyItemToTreeItem( pPropertyValue );
        if( hTreeItem == NULL )
            continue;
        CExtGridCell * pGridCell = pGrid->ItemGetCell( hTreeItem, 1 );
        if( pGridCell == NULL )
            continue;
        ASSERT_VALID( pGridCell );
        pGridCell->Assign( pValueBool );
        if( (pGrid->GetStyle()&WS_VISIBLE) == 0 )
            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 );
        }
    }
As a result, you should not loose focus/selection nor scroll position in any of the tree grid windows inside the property grid control.

Nitesh Singh Dec 2, 2006 - 1:22 AM

In my case also.. when I change the value of one row.. then some of the specific rows should have updated values.. In that case I was calling CExtPropertyGridCtrl::PropertyStoreSynchronize()


can I also use the code....

Technical Support Dec 2, 2006 - 11:03 AM

Yes, this code applicable here.