UWP C++/CX开荒记 第二回 设计思想
概要
UWP开发采用MVVM框架,毕竟UWP和WPF一样采用数据绑定的方式。MVVM是Model-View-ViewModel的简写,具体的含义请查阅相关资料,这里不具体说明了。
实际情况
在C#实现MVVM比较简单,毕竟C#就一个文件,不会拖泥带水,对于C++/CX而言,一个类要两个文件,而且由于拓展,部分的实现必须写进头文件里面。我个人采用的做法是,建立筛选器,把不同级别的文件放进去,当然还是有点乱,这就需要规定好名字空间,另外提一点,在UWP里面最好名字空间采用树形结构,也就是在当前名字空间下再建立名字空间,不然很有可能会出现找不到组件的情况。
实例
这只是一个简单的集合绑定例子,关于分组集合绑定,之后的章节会讲。
Model
//modeltest.h begin
#pragma once
namespace uwpdata = Windows::UI::Xaml::Data;
namespace Test
{
namespace Model
{
[uwpdata::Bindable]
public ref class modeltest sealed
{
public:
modeltest(Platform::String^ str);
property Platform::String^ modelcontent;
};
}
}
//end
//modeltest.cpp
#include "modeltest.h"
using namespace Test::Model;
using namespace Platform;
modeltest::modeltest(String^ key)
{
modelcontent=key;
}
ViewModel
//viewmodeltest.h
#include "modeltest.h"
#include <vector>
namespace uwpclt = Platform::Collections;
namespace WFC = Windows::Foundation::Collections;
namespace Test
{
namespace ViewModel
{
[uwpdata::Bindable]
public ref class viewmodeltest sealed
{
private:
std::vector<Model::modeltest^> items;
public:
viewmodeltest();
property WFC::IVector<Model::modeltest^>^ modellist
{
WFC::IVector<Model::modeltest>^ get()
{
auto arr=ref new Platform::Array<Model::modeltest^>(items.data(),items.size());
auto vec=ref new uwpclt::Vector<Model::modeltest^>;
vec->ReplaceAll(vec);
return vec;
}
}
};
}
}
//viewmodeltest.cpp
#include "viewmodeltest.h"
using namespace Test::ViewModel;
using namespace Platform;
viewmodeltest::viewmodeltest()
{
for(int i=0;i<10;i++)
items.push_back("No:"+i);
}
View应用
使用的方法与C#是类似的,设置集合的模板,绑定数据源到属性,,使用时需设置ItemsSource属性(View控件独有),或者数据上下文,方法有两种:
1. 静态绑定
首先要在页面头文件声明viewmodel的公有属性成员,在构造函数中将其初始化,在绑定时需指明与页面类的相对路径,另外,使用x:bind需要页面具有内部类,也就是标准页面的意思,如果是用外部数据字典是没办法定义x:bind的。本例中若绑定至ListView(假设已经有viewmodeltest的公有属性实例VM):
<ListView x:Name="listview" ItemsSource="{x:bind VM.modellist}">
<ItemsTemplete>
<TextBlock Text="{Binding modelcontent}"/>
</ItemsTemplete>
</ListView>
//MainPage.xaml.cpp
//...省略其它元素
MainPage::MainPage()
{
InitializeComponent();
VM=ref new viewmodeltest;
}
采用代码赋值可以在适当的时候进行刷新,当然是对于集合的情况,如果设定好主动监控触发的方法也可以自动操作集合进行刷新。
静态绑定的耦合度较高,但是性能强,便于调试。如果是需要加载大量的数据,应该优先考虑静态绑定。
2. 动态绑定
这种模式属于动态绑定,在程序运行时会搜索相关属性,无需在页面类里实例化,但是需要控件指定数据上下文:
<ListView ItemsSource="{Binding modellist}">
<ListView.DataContext>
<local:viewmodeltest/>
</ListView.DataContext>
<ListView.ItemsTemplete>
<TextBlock Text="{Binding modelcontent}"/>
</ListView.ItemsTemplete>
</ListView>
总结
WVVM的设计模式可减少后台代码的耦合度,使开发人员更加专注于单一模块的开发,有利于软件工程的实施。最后提示一点,属性是可以通过C++/CX代码直接设置的,但是,如果为了降低耦合度,应优先考虑采用XAML进行绑定。