| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1307 人关注过本帖
标题:在 init 事件用代码新建表单属性与用新建属性对话框新建属性二者有何不同?
只看楼主 加入收藏
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
任何对象都可以添加属性!知道什么叫属性、属性的内部实现机制,对这个问题根本不需要有疑问——属性在语言内部就是一个方法,懂Java或C#之类的都明白。何况我多次示范过给各种控件添加属性的实例,包括最近那次。

[ 本帖最后由 TonyDeng 于 2014-9-15 20:18 编辑 ]

授人以渔,不授人以鱼。
2014-09-15 20:15
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
下面是一个给Container控件添加自定义属性的例子,带下划线开头并注释了的即是。

程序代码:
*---------------------------
* 住户信息显示控件
*---------------------------
DEFINE CLASS C_Household AS Container

    BorderWidth = 2
    SpecialEffect = 0

    _FontName = "微软雅黑"
    PROCEDURE _FontName_Assign(tcValue)
        IF VARTYPE(tcValue) != "C"
            tcValue = "微软雅黑"
        ENDIF
        WITH This
            ._FontName = tcValue
            .SetAll("FontName", ._FontName)
        ENDWITH
    ENDPROC
   
    _FontSize = 9
    PROCEDURE _FontSize_Assign(tnValue)
        IF (VARTYPE(tnValue) != "N") .OR. (tnValue < 9)
            tnValue = 9
        ENDIF
        WITH This
            ._FontSize = tnValue
            .Arrange
        ENDWITH
    ENDPROC

    _Width = 80
    PROCEDURE _Width_Assign(tnValue)
        IF (VARTYPE(tnValue) != "N") .OR. (tnValue < 80)
            tnValue = 80
        ENDIF
        WITH This
            ._Width = tnValue
            .Arrange
        ENDWITH
    ENDPROC
   
    _Height = 16
    PROCEDURE _Height_Assign(tnValue)
        IF (VARTYPE(tnValue) != "N") .OR. (tnValue < 16)
            tnValue = 16
        ENDIF
        WITH This
            ._Height = tnValue
            .Arrange
        ENDWITH
    ENDPROC
   
    * 房号
    _Number = ""
    PROCEDURE _Number_Assign(tcValue)
        IF VARTYPE(tcValue) != "C"
            tcValue = ""
        ENDIF
        WITH This
            ._Number = tcValue
            .lbl_HouseNumber.Caption = ._Number
        ENDWITH
    ENDPROC
   
    * 户主名
    _Name = ""
    PROCEDURE _Name_Assign(tcValue)
        IF VARTYPE(tcValue) != "C"
            tcValue = ""
        ENDIF
        WITH This
            ._Name = tcValue
            .lbl_HouseName.Caption = ._Name
        ENDWITH
    ENDPROC
   
    HIDDEN _Margin
    _Margin = 4
   
    ADD OBJECT PROTECTED lbl_Title1      AS Label WITH Caption = "房号: ",     Alignment = 1, Width = 50, Height = This._Height
    ADD OBJECT PROTECTED lbl_HouseNumber AS Label WITH Caption = This._Number, Alignment = 2, Width = This._Width, Height = This._Height
    ADD OBJECT PROTECTED lbl_Title2      AS Label WITH Caption = "户主: ",   Alignment = 1, Width = 50, Height = This._Height
    ADD OBJECT PROTECTED lbl_HouseName   AS Label WITH Caption = This._Name,   Alignment = 2, Width = This._Width, Height = This._Height
   
    PROCEDURE Arrange
        WITH This
            .SetAll("FontSize", ._FontSize)
            .SetAll("BackStyle", 0)
            WITH .lbl_Title1
                .Height = This._Height
                .Top = This._Margin
                .Left = This._Margin
            ENDWITH
            WITH This.lbl_HouseNumber
                .Width = This._Width
                .Height = This._Height
                .Top = This.lbl_Title1.Top
                .Left = This.lbl_Title1.Left + This.lbl_Title1.Width
            ENDWITH
            WITH This.lbl_Title2
                .Height = This._Height
                .Top = This.lbl_Title1.Top + This.lbl_Title1.Height + This._Margin
                .Left = This._Margin
            ENDWITH
            WITH This.lbl_HouseName
                .Width = This._Width
                .Height = This._Height
                .Top = This.lbl_Title2.Top
                .Left = This.lbl_Title2.Left + This.lbl_Title1.Width
            ENDWITH
            .Width = .lbl_HouseNumber.Left + .lbl_HouseNumber.Width + ._Margin
            .Height = .lbl_HouseName.Top + .lbl_HouseName.Height + ._Margin
        ENDWITH
    ENDPROC
   
    PROCEDURE Resize
        This.Arrange
    ENDPROC
   
ENDDEFINE


这个用法,容器控件中的4个Label,我都使用了Protected修饰,即在外部无法修改这些控件,改为直接给Container赋值自定义属性,然后由这些属性给内部被保护起来的控件统一赋值,这样就不需在外部逐个对容器内部的控件赋值(这是面向对象编程隐藏类内数据的标准用法,C++中类字段默认都是私有的,不对外公开)。这样做是为了防止用户(在面向对象编程中类是设计给程序员使用的,故它有两类用户,除最终程序使用者用户外,使用该类进行编程的程序员也是用户)意外修改类内对象,尤其是当他知晓类内控件属性分布的情况下,他可能去改你不希望被改或没预料到的属性,从而使程序出错——VFP默认类内的数据是公开的。

[ 本帖最后由 TonyDeng 于 2014-9-15 21:04 编辑 ]

授人以渔,不授人以鱼。
2014-09-15 20:52
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
比如这段:
程序代码:
    * 户主名
    _Name = ""
    PROCEDURE _Name_Assign(tcValue)
        IF VARTYPE(tcValue) != "C"
            tcValue = ""
        ENDIF
        WITH This
            ._Name = tcValue
            .lbl_HouseName.Caption = ._Name
        ENDWITH
    ENDPROC


这是给Container添加一个名叫_Name的属性(加下划线是与Container父类原有的Name属性区别),第一行,就等于你在设计对话框中新建属性那个动作(在设计器中其实就往表单中写入那一行代码)。属性名_Assign这个方法,是VFP8新增公开的给属性赋值的方法,只要你在外部使用._Name = "abcde"这样的赋值操作,类就执行这个对应的方法代码,其中"abcde"字符串即是方法中的参数(tcValue)值,从这里,你可以看到给属性赋值在类内部到底干了什么。事实上,VFP所有控件的属性都是这样做的,它可以做任何动作!!!在这里,我把这个属性的值转赋给类内控件lbl_HouseName.Caption。再看看_FontName属性,.SetAll()方法把容器内部4个控件的字体统一设置了,即达到赋值一次,同时调整4个控件的目的,而且外部的程序员无需知道容器内有多少控件以及它们都叫什么名字,这是不需知道的,更方便的是你可以往容器中添加更多的控件,但在外部不用改任何代码,这就是低耦合性。想象一下你用传统的做法,当给容器内增删控件的时候,牵涉到需要改动的地方有多少?


[ 本帖最后由 TonyDeng 于 2014-9-15 22:11 编辑 ]

授人以渔,不授人以鱼。
2014-09-15 21:15
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
回复 9 楼 sylknb
有AddProperty()函数,没有方法。在类中添加自定义属性是像我上面示例那样写,跟内置的属性语法完全一样。其实,内置的属性,也是那样创建出来的,因为它根本上就不是变量。所谓“属性”,真正的面目是方法(即一段函数代码)!

授人以渔,不授人以鱼。
2014-09-15 21:58
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
你要知道,只要是对象,不管那是什么对象,都可以给它添加属性。静态属性是给类整体注入属性,动态属性则多用于给某个具体对象实例添加临时属性(即可以是此对象特有的而从同一类中派生的对象可以没有,救急用)。对前者,在类设计器(或代码)中添加,对后者,用AddProperty()函数添加。

授人以渔,不授人以鱼。
2014-09-15 23:38
sylknb
Rank: 4
等 级:贵宾
威 望:14
帖 子:1547
专家分:184
注 册:2006-6-3
收藏
得分:0 
以下是引用TonyDeng在2014-9-15 21:58:59的发言:

有AddProperty()函数,没有方法。在类中添加自定义属性是像我上面示例那样写,跟内置的属性语法完全一样。其实,内置的属性,也是那样创建出来的,因为它根本上就不是变量。所谓“属性”,真正的面目是方法(即一段函数代码)!
有AddProperty()函数,没有方法?
下面不是方法吗?见图:
图片附件: 游客没有浏览图片的权限,请 登录注册

下面是AddProperty()函数

图片附件: 游客没有浏览图片的权限,请 登录注册
2014-09-16 08:55
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
回复 16 楼 sylknb
这是同一个东西。后面那个函数版本,实际上被转换为前面的方法调用,看参数列表就知道了它是怎么运作的了,而且这是前者的简化版,缺了两个参数,可控性减少。

[ 本帖最后由 TonyDeng 于 2014-9-16 09:20 编辑 ]

授人以渔,不授人以鱼。
2014-09-16 08:57
sylknb
Rank: 4
等 级:贵宾
威 望:14
帖 子:1547
专家分:184
注 册:2006-6-3
收藏
得分:0 
以下是引用liuxingang28在2014-9-15 20:09:15的发言:

新建属性对话框有如下特点:
1. 是在设计模式下为表单或表单集添加属性的唯一方法。
2. 当存在表单集时,新属性被添加到表单集;当不存在表单集时,新属性被添加到表单。
3. 不可能用这种方法为表单或表单集之外的其他控件添加属性。

严格来说,AddProperty 是控件的一个方法,其调用形式类似于函数,是在运行模式下为控件添加属性的方法。

如果再听不懂,我可要打你的屁屁了!
我有的明白了,如下理介对否?
1。<<新建属性对话框>>(设计模式静态或称为静态)的方法只能给表单集或表单添加属性,不能给表单中的控件新建属性。
2。运行模式下AddProperty 方法既可为表单集或表单添加属性也可为控件添加属性。
图片附件: 游客没有浏览图片的权限,请 登录注册
2014-09-16 09:24
liuxingang28
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:山东济南
等 级:贵宾
威 望:47
帖 子:658
专家分:2180
注 册:2014-2-7
收藏
得分:0 
对喽!

泉城飞狐
2014-09-16 09:49
快速回复:在 init 事件用代码新建表单属性与用新建属性对话框新建属性二者有何不 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.023420 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved