• 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 进行解析成对象,我们可以访问对象且修改的值。
    ==> 具体是什么对象的访问,对于对象的访问其有什么意思呢。思考当中。。。


     

  • 相关阅读:
    python--执行文件的绝对路径
    python----slots属性安全类
    linux----LAMP之编译安装apache
    MySQL----alter table modify | change的不同
    数据库5
    数据库4
    数据库3
    数据库2
    数据库1
    MySQL exists 和 not exists 的用法
  • 原文地址:https://www.cnblogs.com/pengxinglove/p/1799133.html
Copyright © 2020-2023  润新知