mrfangzheng

Hope and fear are useless. Be confident, and always be prepared for the worst.
  首页  :: 新随笔  :: 联系 :: 管理

元素和容器, Model and View

Posted on 2008-06-13 17:36  mrfangzheng  阅读(518)  评论(0编辑  收藏  举报

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, …

 

  1. 添加元素
    1. 用户在视图容器viewContainer1中,输入模型数据
    2. 系统创建ModelElement
    3. 视图容器ViewContainer调用ModelContainer的Add方法, viewContainer1.ModelContainer.Add(modelElement);
    4. 模型容器ModelContainer把ModelElement添加到自己的管理范围之内
    5. 模型容器ModelContainer发出ModelElementsAdded事件, 通知所有viewContainer1, viewContainer2, …
    6. 每个ViewContainer响应该事件, 根据ModelElement创建或使用缓存中的ViewElement(可能多个), 并把ViewElement添加到自己的管理范围之内

 

如何做到: 当model被添加到modelContainer中去时, view1, view2自动被分别添加到viewContainer1, viewContainer2中?

元素与容器的关系

  1. 如何表明一个元素在一个容器中? 遍历容器中所有元素时能够找到该元素, 则表明该元素在此容器中
  2. 对元素进行操作之前, 必须先选中它.
  3. 元素应该在被选中和被移除时得到通知.

Model的职责

  1. 保存状态数据
  2. 执行业务逻辑
  3. 发出事件

View的职责

  1. 和Model组合
    1. 组合时在Model上添加事件
    2. 解除组合时移除事件
  2. 响应用户事件
  3. 响应Model事件
  4. 使用ViewContainer的资源, 绘制UI界面 (普通情况, 禁用时, 拥有焦点时, 被选中时)
    1. 完全绘制(和Model组合后或者刷新时调用)
    2. 部分绘制(更新事件发生时)

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

选中过程

  1. modelContainer.Select(model, true/false)
  2. model.IsSelected=true/false;
  3. 触发model.SelectedChangedEvent
  4. 执行事件处理器OnModelSelectedChanged
    1. viewContainer.Select( view, ture/false );
    2. 更新view