`
huozheleisi
  • 浏览: 1239692 次
文章分类
社区版块
存档分类
最新评论

CMFCPropertyGridCtrl: How to Validate and Update Data?

 
阅读更多
Hi, Guys,


I have been trying to validate and update data back to the original objects from a CMFCPropertyGridCtrl derived class CMFCPropList. But in the override of ValidateItemData function, the values obtain from CMFCPropertyGridProperty are always the original (not the edited) values except for combo box selection items. I searched the MSDN and can not find any other functions like GetItemText() etc. for getting the edited value. I could not obtain the edited values.

To update data back to the original objects, I tried to override the OnPropertyChanged(pProp) function, but in debugging, the program never run into the function no matter how the proerties was changed. I also tried to use PreTranslateMessage(msg) of the parent window to catch theAFX_WM_PROPERTY_CHANGED message, but it was also never sent no matter how the properties was changed.

Could anybody give me some clue as how to validate and update data from a property grid control. Any suggestions, tips and help are welcome and greatly appreciated.

Answer1:

I realise this is an old post and you may already have a solution, but having just discovered a method of doing this myself I thought it mighthelp others struggling with this aspect of the feature pack. The following example should provide sufficent code to get you started.

Note that the example assumes theproperties grid is embedded in aderived CDockablePane called CMyProperties. Also note that eachgrid and each item in the grid must be givenanunique ID upon creation. However,do remember to keep all yourcontrol IDs consistent with any existing controls. E.g., if you have a toolbar button that changes the same property, use the same control ID for both. Similarly with menu options and any other dialog controls.

// MyProperties.h
class CMyProperties : public CDockablePane
{
private:
	DECLARE_DYNCREATE( CMyProperties )

protected:
	DECLARE_MESSAGE_MAP()
	afx_msg LRESULT OnPropertyChanged( __in WPARAM wparam, __in LPARAM lparam );

public:
	// Otherclass members...
}
 


// MyProperties.cpp
BEGIN_MESSAGE_MAP( CMyProperties, CDockablePane )
	ON_REGISTERED_MESSAGE( AFX_WM_PROPERTY_CHANGED, OnPropertyChanged )
END_MESSAGE_MAP()

LRESULT CMyProperties::OnPropertyChanged(
    __in WPARAM wparam,
    __in LPARAM lparam )
{
	// Parameters:
	// [in] wparam: the control ID of the CMFCPropertyGridCtrl that changed.
	// [in] lparam: pointer to the CMFCPropertyGridProperty that changed.

	// Return value:
	// Not used.

	// Cast the lparam to a property.
    CMFCPropertyGridProperty * pProperty = ( CMFCPropertyGridProperty * ) lparam;

	// At this point you could simply pass pProperty to the appropriate object
	// and let it handle its owndata validation. However, the wparam can be used
	// togive additional context to the property. For example, if you have two 
	// different class of object in your application, it makes sense to have two
	// seaprateproperty grid controls (one for each object). The following switch
	// deals with this scenario. 

	// Determine which property grid waschanged (wparam is the control ID).
    switch( wparam )
    {
    case( ID_PROPCTRL_CLASS1 ): 
		
		// Note: For consistency, store all your control IDs in resource.h.
		// Pass the appropriate control ID to the CMFCPropertyGridCtrl during
		// creation. Here we've used ID_PROPCTRL_CLASS1 to show that this control
		// relates to all the properties ofobjects of type CClass1.

		// At this point we can simply pass pProperty to the appropriate CClass1
		// object and let it handle its own data validation. The following code
		// should therefore be placed in an appropriate CClass1 method such as
		// pMyClass1->UpdateProperty( pProperty ). I've kept it here to keep this
		// example as simple as possible.

		// Determine which property was changed.
        switch( pProperty->GetData() )
        {
        case( ID_CLASS1_PROP1 ):

			// Note: For consistency, store all your control IDs in resource.h.
			// Pass the appropriate control ID to the CMFCPropertyGridProperty during
			// creation (data member). Here we've used ID_CLASS1_PROP1 to show that 
			// this property relates to class CClass1 member value m_Prop1. Since the
			// object itself should deal with pProperty, you could use this data to 
			// assert when an inappropriate pProperty is passed.

			// Get the property's current value.
            COleVariant v = pProperty->GetValue();

			// The object itself should cast the data to an approriate type (if required),
			//validate the data and set the member via a set accessor method. The object's
			// set accessor method should, in turn, notify all relevant controls that its 
			// member has been updated. Of course, all controls and the set accessor itself
			// should have equality guards to prevent infinite loops.

            break;

        // Add 1 case per additional property control ID.
        }
        break;

    // Add 1 case per additional property grid control ID.
    }

    // Note: the return value is not used.
    return( 0 ); 
}
 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics