WindowsPhone开发笔记(1)—— ViewMoel
废话: 前很长一段时间一直忙于写 guokr reader 和 喂饭 。 现在终于可以 整理一下开发中的有点价值的东西。
额。。。viewmodel 这东西 直面意思就是界面对象。。他里面描述的东西应该只有 数据和业务逻辑 ,他里面不应该与任何与 界面交互相关的东西 (比如控制一个什么控件 ,动画、消息框什么的。。。。。 )发生关系(别想歪了 我故意的。。。)
但是我们在实际使用中vm 中的发生了一些事情 总得让view 知道啊 所以ms 为我们提供了
system.componentmodel.inotifydataerrorinfo
system.componentmodel.inotifypropertychanged
system.componentmodel.inotifypropertychanging
等 通知 接口
我们以inotifypropertychanged 为例来看下结构:
里面有个 事件:propertychanged
vm 通过这些通知接口里面的事件 我们可以告知 view 发生了什么事情 至于 view 管不关心 或者关心什么那就不是 viewmodel的事情了
(注意: 一般来说 要绑定要界面的属性必须实现inotifypropertychanged 属性 也就是说在属性被修改后必须触发 propertychanged事件,同时notify 接口中的事件是在ui 现场中运行的 在跨线程运行的时候一定要注意)
我们在回过头来说vm
一般来说或我都会实现一个 baseviewmodel 吧所需要的实现的接口和基础的方法都在里面实现好
using system;
using system.net;
using system.collections.generic;
using system.componentmodel;
using system.windows;
using system.windows.controls;
using system.windows.documents;
using system.windows.ink;
using system.windows.input;
using system.windows.media;
using system.windows.media.animation;
using system.windows.shapes;
using system.windows.threading;
using system.windows.navigation;
using microsoft.phone.controls;
using system.runtime.compilerservices;
using weifan.utility;
namespace weifan.ui.viewmodel
{
public abstract class baseviewmodel : inotifypropertychanged, inotifypropertychanging,inotifydataerrorinfo
{
dispatcher _dispatcher;
public baseviewmodel()
{
_dispatcher = deployment.current.dispatcher;
}
protected dispatcher dispatcher { get { return _dispatcher; } }
protected phoneapplicationframe phoneapplicationframe { get { return (application.current.rootvisual as microsoft.phone.controls.phoneapplicationframe); } }
private dictionary<string, list<string>> m_errors =
new dictionary<string, list<string>>();
public event propertychangedeventhandler propertychanged;
public event propertychangingeventhandler propertychanging;
public event eventhandler<dataerrorschangedeventargs> errorschanged;
public system.collections.ienumerable geterrors(string propertyname)
{
if (string.isnullorempty(propertyname) ||
!m_errors.containskey(propertyname)) return null;
return m_errors[propertyname];
}
public bool haserrors
{
get { return m_errors.count > 0; }
}
protected bool setproperty<t>(ref t storage, t value,string propertyname)
{
if (object.equals(storage, value)) return false;
this.firepropertychanging(new propertychangingeventargs(propertyname));
storage = value;
this.firepropertychanged(new propertychangedeventargs(propertyname));
return true;
}
protected virtual void firepropertychanging(propertychangingeventargs args)
{
if (propertychanging != null)
{
propertychanging(this, args);
}
}
protected virtual void firepropertychanged(propertychangedeventargs args)
{
if (propertychanged != null)
{
propertychanged(this, args);
}
}
protected virtual void fireerrorschanged(dataerrorschangedeventargs args)
{
if (errorschanged != null)
errorschanged(this, args);
}
protected virtual void adderror(string propertyname, string error, bool iswarning)
{
if (!m_errors.containskey(propertyname))
m_errors[propertyname] = new list<string>();
if (!m_errors[propertyname].contains(error))
{
if (iswarning) m_errors[propertyname].add(error);
else m_errors[propertyname].insert(0, error);
fireerrorschanged(new dataerrorschangedeventargs(propertyname));
}
}
protected virtual void removeerror(string propertyname, string error)
{
if (m_errors.containskey(propertyname) &&
m_errors[propertyname].contains(error))
{
m_errors[propertyname].remove(error);
if (m_errors[propertyname].count == 0) m_errors.remove(propertyname);
fireerrorschanged(new dataerrorschangedeventargs(propertyname));
}
}
}
}
vm 就说到这里吧。。。。下面来说怎么用他。。。。。
最简单的用法的就是在页面代码中 (xaml.cs) 构造出来比如 baseviewmodel basevm = new baseviewmodel();
然后使用 (里面公开的属性 方法 什么的 爱怎么搞怎么搞。。。。。)
如果要在xaml 中binding 的话就要把设置控件(或控件所属的容器)的datacontext设置为该vm (别的方式我还不知道。。。。。。 )
比如:
在xmal.cs 中
layoutroot.datacontent = new xxxxviewmode();
或者:
<grid.datacontext>
<weifan_ui_viewmodel:statusvm/>
</grid.datacontext>
如果是后者的话 vm 会在空间load的时候构造 但是 vm 必须有一个无参数的购找函数。。。
那么
如果vm 由于业务原因 我们总需要在构造的时候需要一些参数进行初始化那么肿么办呢。。。。。。。。。。。
我表示我还没找到好的解决方案。。。。。
我想到的方法有个两个
1、就在xaml.cs 中写吧
但是 我们在xaml 中banding的时候会变得很纠结。。。。
具体怎么纠结 各位自己去体会吧。。。。
2、还是xaml 做vm吧。。。 不过我们得写个初始方法
额。。。 比如。。。
public class statusvm:baseviewmodel
{
bool m_isinitialed = false;
public bool isinitialed
{
get { return m_isinitialed; }
set { setproperty(ref m_isinitialed, value, "isinitialed"); }
}
public void initialization(string statusid)
{ ….... }
}
xaml 中的写法不变
在xaml.cs 的只是需要使用vm 前 构造前 调用initialization 进行初始化。。。。。
摘自 f-sea
推荐阅读
-
学习 Laravel - Web 开发实战入门笔记(1)
-
Spring Cloud和Dubbo整合开发笔记(1)
-
Android入门到精通|安卓/Android开发零基础系列Ⅱ【职坐标】-学习笔记(1)-- 常用控件及资源介绍
-
《微信小程序项目开发实战:用WePY、mpvue、Taro打造高效的小程序》(笔记1)WePY开发环境的安装
-
Windows下使用python-web3.py进行以太坊Dapp开发笔记--第1篇
-
STM32F1开发指南笔记27----ADC采集电压值实验
-
Windows Phone 7 开发探索笔记1——触控操作之Touch
-
大前端【2-1笔记】开发脚手架及封装自动化构建工作流
-
WindowsPhone开发笔记(1)—— ViewMoel
-
manifest.json 解析--手机web app开发笔记(三-1)