think about visual state

时间: 14:40 2010-8-12
背景:已经完成了软件界面的显示,怎么样利用VISUAL STATE 来实现
 类似TAB 控件的功能。
随笔产生的过程:
一边看MSDN或者是其它资源,一边用记事本记录下自己的想法。

因为项目当中利用XAML2CPP.EXE来生成一了些代码。
所以首先要来介绍一个XAML2CPP.EXE所生成的代码.

( 利用设计模式与类模板,以使用框架使用灵活且高效,这是我们应该学习使用的方法,学习怎么样将固定的操作给封装起来)

XAML2CPPXRValue 其统一的表示变量.

// XAML2CPPBase是所有界面(主,子)的创建流程抽象。
XAML2CPPBase 其是实现了SWE所规定的流程的一部分。其有点像模板类设计模式。
XAML2CPPBase其的属性:
protected:
IXRFrameworkElementPtr root;
TCHAR * windowtitle;
TCHAR * xamlresourceid;

XAML2CPPBase其的方法:
public:
GetRoot();
Init();

protected:
InitWindowParms();
SetXAMLSource();
BindObjects();
BindEventHandlers();


其为什么要将IXRVisualHostPtr vhost 放到XAML2CPPPage当中,而不是XAML2CPPBase


XAML2CPPPage其实现了模板类 ==> 其是用于创建界面,界面其是需要vhost的;
功能包括:
protected:CreateHost ( 其只有子类才能够访问,思考这样处理有什么好处)
public:Init ==>CALL CreateHost(); BindObjects(); BindEventHandlers();

//
// class used to implement a panel
//其是用于创建子界面的

XAML2CPPPanel:public XAML2CPPBase
其也是一个XAML文件进行解析,且其进行了BindObjects()与BindEventHandlers()。
这也是对于XAML文件操作封装,且将其看作为一个能够单独存在的(隐)界面,因为其还没有使用

XRWindowCreateParams ,或者其没有添加到VisualHost当中。

XAML2CPPPage 其能够从普通的XAML解析到能够产生界面的原因,其是因为使用了XRWindowCreateParams,
与调用了IXRApplication::CreateVisualHostFromXaml().

一个有意思的推论( 称printf推论)
printf() 其能够输出内容,当需要输出内容的时候我们就可以使用printf()

类似: CreateVisualHostFromXaml其能够使XAML文件显示为界面,
   当需要使XAML文件显示为界面的时候,我们就可以使用CreateVisualHostFromXaml.

由这个而想到一些问题:
一个程序实例当中,其哪些只被允许使用一次呢,哪些使用次数没有约束呢。这些只是使用次数给我们什么启示

了。

IXRApplication 其在整个实例当中,只有一个,且可以到处使用。

我们创建一个界面:要使用 XRWindowCreateParams ,此结构是否为注册一个窗口类提供信息呢。SWE其为我们提

供了一个什么样的窗口类,且窗口类名是什么,窗口处理过程怎么样提供后门由我们来处理呢(XR_HOOKPROC 这

个可以实现)(利用SPY 查看是: class: _XR_VISUAL_HOST_)

使用CreateVisualHostFromXaml 来创建一棵VisualHost,然后调用IXRVisualHostPtr::StartDialog()来进行显示。

当我们需要在一个程序当中显示多个界面的时候,我们也可以使用这个流程了,如果可以,我们应该将这个创建

窗口的流程封装起来,用户只要提供相关XAML(S)与事件处理类,然后调用Show(),就可以创建一个窗口(类似于工

厂类)。


CreateHostFromXaml
ParseXaml
其对于一段XAML的解析,其产生的结果是什么呢.其又是怎么样与总个框架来联系使用的呢 
CreateHostFromXaml 其是创建一个 IXRVisualHostPtr,其本质是一个DependencyObject。

控件集合其是一个DependencyObject,
一个控件其也是一个DependencyObject ==>其说明DependencyObject 其是一个集合,使用了组合模型
==> SWE 的引擎XAML RUNTIME其对于控件的设计思考,其是采用了组合模型.


T_Page, 这是每一个XAML所独有的,其他.H文件还是可以独有,其主要完成XAML2CPPBase当中的BindObjects()
与BindEventHandlers(),我们只要写一个事件处理类,对于此类的要求:其的方法个数与方法名要与

T_Page::BindEventHandlers的数目相同。

呀,话真的,这个时候我才知道模板的威力呀,看来模板很适合写这种编译期( 我希望你能够明白我的意思)的框

架。

现在已经完成了事件的绑定,该是写具体的事件处理代码。在现阶段,
每一个事件代码只要包括类似如下的代码(C#):
 VisualStateManager.GoToState(this, "XXXState", true);

这些视觉行为对象是怎么样与已经创建的VISUAL HOST 发生关联的呢,
(我常常在想,要是让我来设计,我应该怎么样设计呢,采用什么的接口来方便用户的使用了,采用什么的设计模

式来方便自己的开发呢)

那我们来看看MS 的工程师是怎么样解决这个问题,看看是否与我们的思想相同,如果不相同,其为什么要这样设

计呢.

PAGE:
http://msdn.microsoft.com/en-US/library/ee502725.aspx

找两种重要类来看看:
1. Classes for Collection Management
2.Classes for Visual Appearance and Behavior

一个控件其是多个状态组,每一个状态组其又有多个状态,所其需要 集合管理,其类似于C#当中的

VisualStateManager。

每一种状态其是由二个要素所构成的( 动作(行为); 外观),所其要 Classes for visual Appearance and behavior

小结:其将每一个对象看成是有多种状态,且对于状态分类,且由一个组长来负责管理内部细节.
组长其是怎么样与外部联系的呢.

TIPS:使用CODE来进行视觉状态管理,一般是用于用户自定义控件. 这是printf推论,使用printf推论能够为我们

对于问题更深入的思考,从而举一反三。

突然想到:视觉状态,其是以资源的形式,对于资源解析其是产生一个独立对象,我们应该很怎么样访问这些独

立对象,其为什么要叫独立对象呢,独立其是相对于谁而言的呢,

对于Page.XAML(其是用于定义界面的结构)的解析,其是产生一个element tree, 对于其的访问,我们可以通过

IXRFrameworkElementPtr::FindName() 方法,

上面的独立属性与这里的 element tree 是相对应的吗.

突然又想到:这种设计很复杂呀,其的设计目标应该很操作简单明了。

时间:9:02 2010-8-13
IXRVisualStateGroupCollection
其是控件视觉状态部门的主管,部门的直接上级为resource mananger,此部门的作用是什么。

现在的问题:


对于用户控件,我们已经在Page.XAML文件当中定义了此控件的状态,我们怎么样访问找到对象来执行呢,

怎么样找,找哪个对象呢。
是通过IXRFrameworkPtr root::FindName()
还是通过 IXRResourceDictionary::GetItem()。

(IXRResourceDictionary 从其命名当中可以看出,其对于资源对象的管理,其通过“实名制”来管理的,内部的数据

结构为Dictionary, 用XAML当中的name 作为key, value 其是就是资源对象,
思考其为什么对于资源采用Dictionary来存储呢。
==>(类推)Page.xaml(将其称为源文件,其特点是定义了软件界面的结构;将App.xaml称为资源文件,其特点是定义

各种资源)的解析结果,其是tree来进行的存储,所以对于其当中的元素访问,首先要得到一个root ,然后通过
IXRFrameworkPtr::FindName查找对象。
思考其为什么对于UI CONTROL 采用Tree来存储呢。
因为UI CONTROL 之间其存在一种一对多的关系,采用TREE来表示是比较好的,而资源当中对象之间但没有这

种很强关系,更多的是一种松散关系。
)


用代码创建一个视觉状态组。
1. 其是使用IXRApplication::CreateObject(IID,Object) 方法来创建一个空的IXRVisualStateGroupCollection对象。
==> 在SWE当中,所有对象其均是要由大管家IXRApplication来负责招聘,然后放到哪个部门,由部门经理来管理

。这种设计方法其什么优点呢,1.采用统一方式创建对象,有利于管理与使用,从设计模式上讲,其是采用了工

厂模式。值得学习这种设计思想。

2.同样还是使用CreateObject来创建多个IXRVisualStateGroup, 
且每一个IXRVisualStateGroup定义用户控件(IXRUserControl)每一种状态下控件的外观与内部各种状态之间的变

迁(通过IXRVisualState,IXRVisualTransitions,同样其的创建也是通过大管家)

3.将每一个IXRVisualStateGroup 添加到IXRVisualStateGroupCollection当中,其通过调用

IXRVisualStateGroupCollection的父类IXRCollection<In_T,Out_T>::Add,

( IXRVisualState,IXRVisualTransitions ,其是通过什么样方法添加到IXRVisualStateGroup当中的呢,由于

IXRVisualStateGroup其并不是一个集合对象,所以不能用上面的方法.

其首先对于IXRVisualState(S) 是通过IXRVisualStateCollection来管理的,IXRVisualTransitions是通过

IXRVisualTransitionCollection来进行管理的,这此集合通知IXRVisualStateGroups::SetStates

(),IXRVisualStateGroups::SetTranition来进行添加。
其为什么要这样设计呢,其采用了策略设计模式,从而解耦,方便REUSE
)

4.万事具备,只少东风,此东风是什么呢,我们写这个VisualState是对于控件的,现在已经写好了VisualState,是

时候将其与控件绑定了。


MS的SWE 设计师其会怎么样设计这个方案呢?

其是先要生成一个IXRFrameworkElement ,调用IXRFrameworkElement父类

IXRDependencyObject::SetAttachedProperty(const WCHAR*,IXRDependencyObject*)
(一个元素其有许多的属性,对于这些属性的管理采用Dictionary来管理)
KEY : VisualStateManager.VisualStateGroups
value: IXRVisualStateGroupCollection object.

然后,将此IXRFrameworkElement 添加到 用户控件当中通过调用IXRUserControl::SetContent。

推论:所有属性(附加属性,也包括资源)其均要通过IXRFrameworkElement ,然后通过IXRFrameworkElment,

转交给IXRUserControl( 其他内置控件这是这样吗). 转交给IXRUserControl其有什么用处呢。


==> 重要特点:各种具体的功能均是分配相关部门来处理,但这些部门其是没有执行权利,
权利均集中在Control 当中,其为什么要这样设计呢。其是隐藏具体很复杂的细节,只给用户一个统一的接口。这

就是面向对象的思想体现呀。因为用户其只是知道控件有状态的feature,然后用户操作接口就可以了。

==> 以控件为主角,其他均是配角,用户只下命令给主角,主要将任务分配配角,配角具体执行。

==>  解决了控件与资源之间的关系


那怎么要访问执行吗。
其分为两种情况:
1.用户在XAML当中已经定义了VisualState.
2.手动使用代码创建.


反思:视觉状态其单独地定义在资源文件当中,其总是与控件在一起的(具体在ControlTemplate),SWE其对于

ControlTemplate当中的内容的新的规定:


Note: 
The contents of a ControlTemplate defined in Microsoft Silverlight 2 XAML cannot be accessed from C++.

Therefore, visual states and visual-state groups that were defined in a ControlTemplate in the source XAML for your application cannot be accessed in Silverlight object tree. 

其说明了什么意思呢。
1.是什么XAML能够用C++访问。其不能够访问其说明什么意思,难道是无效的吗,XAML RUNTIME 不对其进行解

析。

2. 其是规定ControlTemplate当中的内容不能访问,我们能否不将Visual states and  Visual-state groups 定义在

ControlTemplate当中其应该就可以访问了吧。这能否可行吗.
刚刚看一下XAML文件,确实允许VisualState 不定义在ControlTemplate,


且发现将VisualState定义在ControlTemplate当中的都改写内置控件所造成。
对于用户自定义控件则是直接定义到<UserControl ...> ...</UserControl>当中

3.Silverlight object tree 其包括哪些部分呢。是资源部分和源文件部分吗
 

控件EXPOSE 的操作接口是什么呢。

IXRControl::GoToVisualState

virtual HRESULT STDMETHODCALLTYPE GoToVisualState(
    const WCHAR *pStateName,
    bool UseTransitions
) = 0;

其只要提供控件所具有视觉状态的名称就可以呢。
注意首先要找到控件:IXRFrameworkPtr::FindName(), 其要找哪一个控件呢,对于用户自定义控件,应该是找根结

点。直接通过IXRVisualHostPtr::GetRootElement()方法吧。
然后再调用GotoVisualState。

在C#当中有VisualStateManager
其的使用方法
VisualStateManager.GotoState(控件对象,状态名,[true,false]);


后续:
刚刚看了一下VisualTransition 所新认识,我对于VisualTransition的看法仅仅停在VisualState这个层面上,

VisualTransition 其是指控件从一个状态过渡到另一个状态。
但我需要从一个动画过渡到另一个动画的时候,我们能否采用VisualTransition思想帮忙呢.

 
框架其是为什么要采用模板技术,有什么技术能够代替之吗
什么特点下最好使用模板呢。
使用模板编程的思路是什么,在使用这个模板的时候我要想什么呢。


在写过程当中看一篇关于使用C++创建一个状态的方法
PAGE:http://www.cnblogs.com/ddggo/archive/2010/08/05/1793161.html
文章很详细的介绍创建过程,值得一看,且文章的作者丁一是一个好人呀,因为我EMAIL 他,要XAML2CPP.EXE
他很快地就给了我. 呵呵。。

刚刚想一下文章的一段话:
“但是如果需要动态读取数值并进行设置的话,就需要使用本地的C++代码来编写各个VisualState”
我觉得写成XAML文件其应该能够实用这种需求,
因为XAML 通过XAML RUNTIME 进行解析成对象,我们可以访问对象且修改的值。
==> 具体是什么对象的访问,对于对象的访问其有什么意思呢。思考当中。。。


 

原文地址:https://www.cnblogs.com/pengxinglove/p/1799133.html