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 the AFX_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 might help  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 the properties  grid is embedded in a derived  CDockablePane called CMyProperties. Also note that each grid  and each item in the grid must be given an unique ID upon creation. However, do remember to keep all your control  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:
	// Other class  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 own data  validation. However, the wparam can be used
	// to give  additional context to the property. For example, if you have two 
	// different class of object in your application, it makes sense to have two
	// seaprate property  grid controls (one for each object). The following switch
	// deals with this scenario. 

	// Determine which property grid was changed  (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 of objects  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 ); 
}
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值