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 » property grid question Collapse All
Subject Author Date
Rado Manzela Nov 28, 2007 - 10:33 AM

I’m using CExtPropertyGridCtrl in my project. One of properties is check box. I need to disable some properties (make them read-only) when checkbox is unchecked (react to clicks on this checkbox). How can I do this?

I’ve created custom cell from checkbox cell (it contains my dialog’s callback function’s address + dialog’s "this") and overrided OnClick() function. The problem is that it seems OnClick is called at some copy of cell so it has uninitialized callback address. Why is it cloned? I’m creating it this way (important parts only):


CCellCheckBox *myCk;
myCk = (CCellCheckBox*)iCreate(RUNTIME_CLASS(CCellCheckBox),m_cat);
myCk->SetCallback(&EnableItems,this);
myCk->SetAutoTextMode(true);


CExtGridCell* iCreate(CRuntimeClass *rtc,CExtPropertyItem* parent)
{
CExtGridCell* val;
i.pv = new CExtPropertyValue(dName,NULL,NULL,false,false);
val = i.pv->ValueActiveGetByRTC(rtc);
parent->ItemInsert(i.pv);
return val;
}

Anyway isn’t there some smarter way how to notice parent that some cell was clicked? I mean some notification message. I’m creating own cell class just to catch click and send it to dialog which is hosting the grid.
Thank you!

Rado Manzela Nov 30, 2007 - 6:58 AM

Thank you, now I’ve got it working :)


BTW: I would suggest you to make built-in support for easier disabling of items, it is quite big code which must be written :)

Suhai Gyorgy Nov 30, 2007 - 1:52 AM

If you create a custom cell class derived from any of the CExtGridCell*** classes, and you add a new member variable to this new class, then you should also override its Assign method. This method is called when the cell is "cloned", as mentioned by Support. Example follows.
In .h file:

class CCellCheckBox : public CExtGridCellCheckBox
{
public:
	DECLARE_SERIAL( CCellCheckBox );
	IMPLEMENT_ExtGridCell_Clone( CCellCheckBox, CExtGridCellCheckBox );
	CCellCheckBox( CExtGridDataProvider * pDP = NULL );
	virtual void Assign( const CExtGridCell & other );
...
private:
	bool m_bNewMember;
};
In .cpp file
...
#include "SomeFile.h"
 
IMPLEMENT_SERIAL( CCellCheckBox, CExtGridCellCheckBox, VERSIONABLE_SCHEMA|1 );
 
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
...
CCellCheckBox::CCellCheckBox( CExtGridDataProvider * pDP /* = NULL */ )
	: CExtGridCellCheckBox( pDP )
	, m_bNewMember(false)
{
}
...
void CCellCheckBox::Assign( const CExtGridCell & other )
{
	ASSERT_VALID( this );
	CExtGridCellCheckBox::Assign( other );
	CCellCheckBox *pCell = DYNAMIC_DOWNCAST(CCellCheckBox, (&other));
	if ( pCell != NULL )
		m_bNewMember = pCell->m_bNewMember;
}
...

Technical Support Nov 29, 2007 - 2:11 PM

Each CExtPropertyValue property value inside the property store tree contains two CExtGridCell*** grid cell objects representing active and default/initial values. The CExtPropertyGridCtrl property grid control is designed as a container for one or more CExtPropertyGridWnd-based tree grid windows displaying the content of a property store. By default, two tree grids are created: CExtPropertyGridWndCategorized and CExtPropertyGridWndSorted. These tree grid windows contain copies of active grid cells from each property value. When some grid cell editing is complete in the active tree grid window, then cell’s value is assigned to cells in other inactive/invisible tree grid window(s) and to active cell value in the corresponding CExtPropertyValue property value object. We assume you have a CExtPropertyValue* pointer and you should disable its cells in both property grid and property store:

CExtPropertyValue * pPvToDisable = . . .
CExtPropertyGridWnd * pPGC = . . .
      //
      // first, we should disable property value’s cells inside property store
      //
CExtGridCell * pCellActive = pPvToDisable->ValueActiveGet();
      ASSERT_VALID( pCellActive );
      pCellActive->ModifyStyle( __EGCS_READ_ONLY, 0 ); // disable it
CExtGridCell * pCellDefault = pPvToDisable->ValueDefaultGet();
      ASSERT_VALID( pCellDefault );
      pCellDefault->ModifyStyle( __EGCS_READ_ONLY, 0 ); // disable it
      //
      // second, we should disable cells in tree grids
      //
CTypedPtrArray < CPtrArray, CExtPropertyGridWnd * > arrGrids;
      pPGC->OnPgcQueryGrids( arrGrids );
INT nGridIdx = 0;
      for( ; nGridIdx < arrGrids.GetSize(); nGridIdx ++ )
      {
            CExtPropertyGridWnd * pGrid = arrGrids[ nGridIdx ];
            ASSERT_VALID( pGrid );
            HTREEITEM hTreeItem = pGrid->PropertyItemToTreeItem( pPvToDisable );
            if( hTreeItem == NULL )
                  continue;
            CExtGridCell * pCellDst = pGrid->ItemGetCell( hTreeItem, 1 );
            if( pCellDst == NULL )
                  continue;
            ASSERT_VALID( pCellDst );
            pCellDst->ModifyStyle( __EGCS_READ_ONLY, 0 ); // disable it
            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 );
            }
      }