• 关于DELPHI的布局


    以下文章载自:【巴蛮子的破新茅屋】http://blog.csdn.net/bamanzi/archive/2006/02/11/596962.aspx

    Windows编程的习惯是直接指定控件的座标和大小,而UNIX下面的习惯是在容器里面堆放,用不同的layout manager来控制布局(java,wx等也是这种思想)。这也是为什么Windows程序的对话框一般都不让改变大小(因为这意味着要自己写很多代码逐步调整子控件的位置),而UNIX下一般都可以。Delphi程序原来有Align属性来控制控件对那边靠拢。但如果想要一个控件固定离左边、右边有多远,得用D6开始提供Anchors属性。

    所以DELPHI提供3种布局属性:Align, Anchor,和 Constraint。基本能满足布局设计的需要。

    这样还是不够的,比如有七八个按钮顺排或者表格式布局,这在D2006里面可以用新增的TFlowPanel和TGridPanel来实现。

     

    TFlowPanel和TGridPanel的使用方法:

    http://edn.embarcadero.com/article/33421

    呵呵,没找到中文说明的,只能看看E文了。里面的DEMO无法DOWN。

    其中有一个事情要注意:任何一个控件被放到这两个布局上后,无法调整位置,DELPHI提供了一种方法,就是选择要调整的控件,在属性窗体的最下面会出现和布局有关的属性,进行调整就可以了。TFlowPanel有ControlIndex。TGridPanel有column,row,columnspan,rowspan。

       

    评价

    DELPHI提供的GridPanel貌似很好,但是使用起来实在不方便。我自己用GridPanel准备画一个人口信息的输入界面,结果画了一会就觉得烦了,根本没办法用。考虑再三,还是自己写一个。

    至少提供如下功能:

    1.能够在设计状态用鼠标调整行的行的宽度和列的高度。

    2.panel的宽度和高度应该随着里面行和列的高度和宽度的变化而变化。而不应该是像GridPanel,宽度和高度不边,而让行和列的值来适应GridPanel。

    3.能方便的增加和删除行和列。

    4.放入pane中的控件的宽度要随着所在格子的宽度变化而变化。

    开发思路:

    1.从TCustomGridPanel继承。

    2.在设计状态当鼠标移动到网格线上的时候,Cursor变成可crHSplit和crVSplit,(可以通过继承WMSetCursor来实现)

    3.设计状态,当在网按住鼠标并移动的时候,修改对应的格子的大小(可以通过继承WMLButtonDown,WMLButtonUp,和WMMouseMove来实现)

    4.当Panel上放入一个控件的时候,自动设置到对应格子的宽度(可以通过继承AlignControls来实现)。

    5.增加RowCount和ColumnCount属性,可以通过设置这两个属性来设置行和列的总数。

    效果:

       

     

     

    可惜,这个GIF无法显示鼠标移动到网格中的时候改变鼠标形状的情况。

    DELPHI问题

    在写这个panel的时候发现一个问题,可能是DELPHI的BUG

    ExtCtrls单元第3500行,procedure TCustomGridPanel.AlignControls(AControl: TControl; var Rect: TRect);方法中,代码如下:

    AnchorSubset := AControl.Anchors * [akLeft, akRight];

    if AnchorSubset = [akLeft] then

    NewBounds.Left := CellRect.Left

    else if AnchorSubset = [akRight] then

    NewBounds.Left := Max(CellRect.Left, CellRect.Right - AControl.Margins.ExplicitWidth)

    else

    NewBounds.Left := Max(CellRect.Left, CellRect.Left + ((CellRect.Right - CellRect.Left) - AControl.Margins.ControlWidth) div 2);

    这个应该是一个明显的BUG,如果Control的Anchors同时设置了akLeft和akRight,则系统就不再处理,也就是前面提到的如果用GridPanel,放到PANEL上的控件无法根据格子的宽度自动调整宽度。

    修复方法:增加一个判断就可以:

    AnchorSubset := AControl.Anchors * [akLeft, akRight];

    //hl add 20090415原来控件没有提供对 Anchors = akLeft, akRight的处理

    if AnchorSubset = [akLeft, akRight] then

    begin

    NewBounds.Left := CellRect.Left;

    NewBounds.Right := CellRect.Right;

    end

    else begin

    if AnchorSubset = [akLeft] then

    NewBounds.Left := CellRect.Left

    else if AnchorSubset = [akRight] then

    NewBounds.Left := Max(CellRect.Left, CellRect.Right - AControl.Margins.ExplicitWidth)

    else

    NewBounds.Left := Max(CellRect.Left, CellRect.Left + ((CellRect.Right - CellRect.Left) - AControl.Margins.ControlWidth) div 2);

    NewBounds.Right := NewBounds.Left + Min(CellRect.Right - CellRect.Left, AControl.Margins.ExplicitWidth);

    end;

  • 相关阅读:
    面向对象之绑定方法与非绑定方法
    Django-admin源码解析
    单例模式
    Django-admin管理工具
    Django-CBV
    叠加装饰器,三元表达,生成,调用,递归
    迭代器与生成器
    有参装饰器
    储备知识与装饰器
    文件修改
  • 原文地址:https://www.cnblogs.com/barryhong/p/1429073.html
Copyright © 2020-2023  润新知