早期的FMX控件都是TStyledContronl的,也就是控件都支持Style,可以粗粗理解为控件只有外观颜色上的变化,都是控件外观的样子是一样的。后来,部分控件增加了Presentation层,这一层支持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控件提供了几种界面外观,采用了MVP设计模式,Mode是TDataModel,View是TStyledPresentation,P是TPresentationProxy。采用了MVP模式设计,就可以比较方便是实现了外观的变换。现在版本的DELPHI,从TComponent就开始用观察者模式进行内部的通信,MVP模式的消息通信,还采用了发布和订阅模式(这两种模式,有人说是一样,有人说不一样,在Delphi中,好像实现的是不一样,使用目的也不大一样,TComponent内部的TObservers纯粹是内部使用的,而发布和订阅模式订阅模式是单独实现的,在System.Messaging.pas,我们可以拿来使用,进行类(实例)间的通信)。TPresentedControl控件包含了Mode(Data),View(TStyledPresentation,对应具体的控件,比如Tedit就是TStyledEdit),在FMX中也叫Reciver或者presentation,就是控件的外观。Presenter(TPresentationProxy)是统一的,继承自TMessageSender,负责TPresentatedControl和presentation间的通信协调(也就是MVP里的P的角色)。当然presentation和mode间是解耦的,所以控件可以有各种外观样式。
有了MVP模式,实现外观变化是有了,都是代价也不少,比如具体控件的Style和Mode是设计,是要化不少心思的。看TEdit的代码实现,就比简单的TEdit多了好多。
还有,FMX的ListBox,ListView不是TPresentedControl控件,但是也实现了复杂的外观变化,不知道为什么。。。。
Firemonkey 的Presentation控件初步了解
原文:https://www.cnblogs.com/jankerxp/p/11177998.html