Model and View
Model : 逻辑上全部数据
View : 用有限的计算机资源展现Model的全部或者一部分.
如果Model数据太多, View需要
- 展示Model的很小一部分. 比如: 用窗口展现文档的一部分, 其他部分使用Scrollbar来滚动.
- 根据View可用资源的数量, 对Model进行简化. 比如: 使用缩略图, 对大量的对象不显示细节.
- 重用View资源. 当Model的一部分已经不需要展现在View中时, 立刻解除这部分Model占用的资源.
元素和容器
View容器viewCotainer1, View元素view11, view12, view13...
View容器viewCotainer2, View元素view21, view22, view23...
Model容器modelContainer, Model元素model
其中,View元素view11, view12, view21, view22都引用model, 并且监听model事件, 但model对view一无所知
ViewElement, ViewContainter都是被动的, 分别受ModelElement和ModelContainer的驱动
ViewContainer需要维护一个当前选中的ViewElement的列表(可能不需要表现出来)
ViewContainer:掌握着一定数量的资源.比如: Windows 绘图系统可以看成一个视图容器, 拥有GDI资源.
ViewElement:通过使用少量容器中的资源来表现一个ModelElement.
View容器中的资源不是无限的, 因此当一个ModelElement被删除时, 表现它的ViewElement可以被删除, 也可以被缓存, 以后指向其他ModelElement
用户对容器的操作包括: 添加n个元素, 删除n个元素, 选择n个元素
用户对模型容器的操作必须通过视图容器来完成,
如下:用户调用视图容器, 视图容器调用模型容器, 模型容器执行操作后, 用事件通知所有的视图容器
用户====>视图容器ViewContainer1====>模型容器ModelContainer---------->所有视图容器ViewContainer1, ViewContainer2, …
- 添加元素
- 用户在视图容器viewContainer1中,输入模型数据
- 系统创建ModelElement
- 视图容器ViewContainer调用ModelContainer的Add方法, viewContainer1.ModelContainer.Add(modelElement);
- 模型容器ModelContainer把ModelElement添加到自己的管理范围之内
- 模型容器ModelContainer发出ModelElementsAdded事件, 通知所有viewContainer1, viewContainer2, …
- 每个ViewContainer响应该事件, 根据ModelElement创建或使用缓存中的ViewElement(可能多个), 并把ViewElement添加到自己的管理范围之内
如何做到: 当model被添加到modelContainer中去时, view1, view2自动被分别添加到viewContainer1, viewContainer2中?
元素与容器的关系
- 如何表明一个元素在一个容器中? 遍历容器中所有元素时能够找到该元素, 则表明该元素在此容器中
- 对元素进行操作之前, 必须先选中它.
- 元素应该在被选中和被移除时得到通知.
Model的职责
- 保存状态数据
- 执行业务逻辑
- 发出事件
View的职责
- 和Model组合
- 组合时在Model上添加事件
- 解除组合时移除事件
- 响应用户事件
- 响应Model事件
- 使用ViewContainer的资源, 绘制UI界面 (普通情况, 禁用时, 拥有焦点时, 被选中时)
- 完全绘制(和Model组合后或者刷新时调用)
- 部分绘制(更新事件发生时)
Model元素:View元素是1:n的关系
View元素可以通过直接引用找到相应的Model元素, 而在某个容器中找Model元素对应的所有View元素则需要一定的算法.
IModelContainer<M>
- 容器事件: ElementsAdded, ElementsRemoved
- Add(M[]), RemoveSelectedElements(), 必须触发上述事件
- 获得选中 M[] SelectedElements { get; }
- 获得选中集合中最后的元素 M SelectedElement { get; }
- 清除选中 void ClearSelection();
IViewContainer<M>
- 得到ModelContainer的引用 IModelContainer<M> ModelContainer { get; set; }
- IViewElement[] SelectedElements { get; }
- Add(IViewElement<M>[]), RemoveSelectedElements()
IModelElement
- 属性改变事件 event EventHandler XxxChanged;
- 选中改变事件 event EventHandler SelectedChanged;
- bool IsSelected { get;set; }
IViewElement<M>
- 得到该View元素对应的Model元素 M ModelElement { get; set; }
- 根据model元素更新界面void UpdateViewElement();
- 事件: ModelSelected, UpdatingViewElement
选中过程
- modelContainer.Select(model, true/false)
- model.IsSelected=true/false;
- 触发model.SelectedChangedEvent
- 执行事件处理器OnModelSelectedChanged
- viewContainer.Select( view, ture/false );
- 更新view