Firemonkey 的Presentation控件初步了解(1)

早期的FMX控件都是TStyledContronl的,也就是控件都支持Style,可以粗粗理解为控件只有外观颜色上的变化,但是控件外观的样子是一样的。后来,部分控件增加了Presentation层(控件继承自TPresentedControl),这一层支持StyledPresentation。支持Presentation层的控件不仅是外观颜色上的变化,还有外观样子上的变化,如TEdit, TGrid,TComboEdit(FMX下,这个控件和TComboBox是不一样的,而且TComboBox也不是TPresentedControl控件),TCalendar等常用控件也是继承自TPresentedControl。

但是FMX.StdCtrls下的控件,虽然继承自TPresentedTextControl或基类TPresentedControl, 如Button,Label,Panel,GroupBox等,实际是不支持Presentation的,还是TStyledControl控件。这里是通过TPresentedControl类的LoadPresentation()方法进行判别,支持Presentation的,是有专门PresentationName的,而不支持Presentation的,是采用默认名称的,直接就交给TPresentedControl的父类TStyledControl负责。有PresentationName的控件,通过一个单例对象TPresentationProxyFactory(在FMX.Presentation.Factory.pas 单元)管理其PresentationName和TPresentationProxy。支持Presentation的控件PresentationName和其对应的TPresentationProxy是在系统启动的时候就加载好了,这是通过支持Presentation的控件的相应Style单元的初始化部分initialization进行的,比如TEdit控件有FMX.Edit.Style.pas,其initialization节调用了函数: TPresentationProxyFactory.Current.Register(TEdit, TControlType.Styled, TStyledPresentationProxy<TStyledEdit>);  TGrid控件也有相应的FMX.Grid.Style.pas。

TPresentedControl控件提供了几种界面外观,采用了类似MVC设计模式的分层设计。各层的基类是:Mode是TDataModel,View是TStyledPresentation,Controler是TPresentedControl(控件自身)。比如对于TEdit控件,M是TCustomEditModel,V是TStyleEdit,C是TCustomEdit(控件自己)。

TPresentedControl控件的分层设计模式和常用的MVC不同(也不同于MVP)。Controler和Model有一一对应关系,Controler拥有Model,Controler直接调用Model;但是Vew(Style)是未确定的,也就是View和Controler是完全分离的(View在设计时,是在控件装载时载入的通过控件(TPresentedControl)的Loaded()方法;所以在运行时,我们可以定制的控件View(也就是Style)替代控件的默认View(Style),而不用额外创建一个控件。这是通过TPresentedContro的事件OnPresentationNameChoosing来实现);既然View(Style)是未确定的,所以Model和View之间的通信就有两种情况,一是Model到View,因为不知道具体的View,所以在设计时采用了代理设计模式,代理类有TPresentationProxy及其子类TStyledPresentationProxy,以及其它的一些辅助类,实现了Model到View的通信,二是View(Style)到Model的通信,由于Model是已知的,所以直接调用Model方法。这里的关键是Model到View(Style)的消息通信实现。

通过分层设计模式,实现外观变化是有了,但是代价也不少,比如具体控件的Style和Mode的设计,是要化不少心思的。看TEdit的代码实现,就比简单的TEdit复杂了好多。

另外,FMX的ListBox,ListView不是TPresentedControl控件,但是也实现了复杂的外观变化.......

原文地址:https://www.cnblogs.com/jankerxp/p/11177998.html