wxWidgets和MVVM模式 3

    上回说到数据与界面基本分离, 并可以进行单元测试.

    这次的目标是仿照MVVM的模式, 进行数据和事件的绑定, UI与事件分离.

 

     首先, 新建一个MyViewModel类,来保存数据和事件函数. UI需要更新Lebel, 需要监听MyViewMode中数据更新.因此引进了观察者模式.

Code Snippet
  1. class wxString;
  2. struct ISystemEventListener
  3. {
  4.     virtual void OnSystemEvent(const wxString& propertyName) = 0;
  5. };
  6.  
  7. struct ISystemEventDispatcher
  8. {
  9.     virtual bool RegisterListener(ISystemEventListener* pListener) = 0;
  10.     virtual bool RemoveListener(ISystemEventListener* pListener) = 0;
  11.     virtual void OnSystemEvent(const wxString& propertyName) = 0;
  12. };

   

    这样在MyViewModel中保存其成员就可以监听事件了. MyViewModel方法如下

Code Snippet
  1. class MyViewModel
  2. {
  3. public:
  4.     void OnClickButton(wxCommandEvent& event);
  5.     wxString m_Name;
  6.     SystemEventDispatcherImp m_Listener;

 

 

    在UI类MyDialog需要继承观察者接口, 然后建立如下模板, 就可以对数据和更新事件的进行监听

Code Snippet
  1. template<class T>
  2. void MyDialog::SetViewData( boost::shared_ptr<T> pViewModel )
  3. {
  4.     wxStaticText* pText = (wxStaticText*) FindWindow(ID_LABEL);
  5.     pText->SetValidator(wxGenericValidator(&(pViewModel->m_Name)));
  6.  
  7.     pViewModel->m_Listener.RegisterListener(this);
  8. }

 

   最后一步, 把MyViewModel中的事件函数绑定到MyModel的button上. 可以使用wxWidgets的方式, 对MyDialog压入EventHandler, 如下

    MyViewDialog继承自wxEvtHandler, 并绑定事件. 完整MyViewDialog如下

Code Snippet
  1. class MyViewModel: public wxEvtHandler
  2. {
  3. public:
  4.     MyViewModel(void);
  5.     ~MyViewModel(void);
  6.     void OnClickButton(wxCommandEvent& event);
  7.     wxString m_Name;
  8.     SystemEventDispatcherImp m_Listener;
  9. private:
  10.     DECLARE_EVENT_TABLE()
  11. };

 

Code Snippet
  1. BEGIN_EVENT_TABLE(MyViewModel, wxEvtHandler)
  2.     EVT_BUTTON(ID_BUTTON, MyViewModel::OnClickButton)
  3. END_EVENT_TABLE()
  4. void MyViewModel::OnClickButton( wxCommandEvent& event )
  5. {
  6.     m_Name = MyData::GetName();
  7.     m_Listener.OnSystemEvent(_T("Name"));
  8. }

 

 

    接下来修改 MyDialog::SetViewData 函数 调用PushEventHandler()即可. 如下

   

Code Snippet
  1. template<class T>
  2. void MyDialog::SetViewData( boost::shared_ptr<T> pViewModel )
  3. {
  4.     wxStaticText* pText = (wxStaticText*) FindWindow(ID_LABEL);
  5.     pText->SetValidator(wxGenericValidator(&(pViewModel->m_Name)));
  6.  
  7.     PushEventHandler(pViewModel.get());
  8.  
  9.     pViewModel->m_Listener.RegisterListener(this);
  10. }

 

    先在基本完成.但

   1. 以m_Name绑定ViewMode中的数据, 这个依赖不好

   2. MVVM模式有UI的配置文件, 可以填写属性自动绑定ViewModel类, wxWidgets也有xml的配置文件, 是不是也可以这样做呢

 

  下一回就以上边的两点为目标.

posted @ 2012-03-14 23:41  柿子院  阅读(1745)  评论(1编辑  收藏  举报