Sign in Join
Wiki copytemporary

Anchor Sides/ru: what changed

Revision 3 to 4. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11Есть несколько новых свойств и методов для автоматического расположения элементов управления. Теперь вы можете настроить элементы управления для поддержания определённого расстояния до других элементов управления или центрирования относительно других элементов управления. Смотрите пример ниже.
22
33Каждая из четырёх сторон элемента управления (Left, Top, Right, Bottom) теперь может быть прикреплена/привязана к стороне другого элемента управления. Например, теперь вы можете привязать левую сторону TEdit к правой стороне TLabel. Каждый раз, когда Label перемещается или меняет размер, левая сторона Edit будет следовать за ней, что обычно приводит к перемещению Edit параллельно Label.
44
55# Пример 1
66
7-```
7+```text
88+--------+ +-------+
99| Label1 | | Edit1 |
1010+--------+ | |
1111 +-------+
1212```
1313
1414## В коде
1515
1616``` pascal
1717Edit1.AnchorSide[akLeft].Side := asrRight;
1818Edit1.AnchorSide[akLeft].Control := Label1;
1919Edit1.Anchors := Edit1.Anchors + [akLeft];
2020```
2121
2222Вы можете задать расстояние с помощью свойств BorderSpacing:
2323
2424``` pascal
2525Edit1.BorderSpacing.Left := 10;
2626```
2727
2828То-же самое может быть сделано с помощью метода:
2929
3030``` pascal
3131Edit1.AnchorToNeighbour(akLeft, 10, Label1);
3232```
3333
3434## Примечания
3535
3636**Edit1.Left** будет следовать за **Label1.Left+Label1.Width**, но не наоборот. Это означает, что перемещение Label1 будет вызывать перемещение Edit1. Но перемещение Edit1 будет отменяться LCL. Если вы также привяжете правую сторону Label1 к левой стороне Edit1, вы создадите кольцо и в сочетании с некоторыми другими свойствами авторазмера это приведёт к циклу. Это игнорируется LCL или автоматически исправляется, когда Parent.AutoSize установлено в True.
3737
3838## С помощью редактора якорей
3939
4040Редактор якорей - плавающее окно, доступное через меню **View / Anchor Editor** или через кнопку в свойстве **Anchors** в инспекторе объектов.
4141
4242![](/wiki-images/6/6d/Anchoreditor.png)
4343
4444# Пример 2
4545
4646Вы можете привязать верхний край Edit для следования за верхним краем Label:
4747
4848 +--------+ +-------+
4949 | Label1 | | Edit1 |
5050 +--------+ | |
5151 +-------+
5252
5353``` pascal
5454Edit1.AnchorSide[akTop].Side := asrTop;
5555Edit1.AnchorSide[akTop].Control := Label1;
5656Edit1.Anchors := Edit1.Anchors + [akTop];
5757```
5858
5959То-же самое может быть сделано с помощью метода:
6060
6161``` pascal
6262Edit1.AnchorParallel(akTop,0,Label1);
6363```
6464
6565# Пример 3
6666
6767Вертикальное центрирование Edit относительно Label:
6868
6969 +-------+
7070 +--------+ | |
7171 | Label1 | | Edit1 |
7272 +--------+ | |
7373 +-------+
7474
7575``` pascal
7676Edit1.AnchorSide[akTop].Side := asrCenter;
7777Edit1.AnchorSide[akTop].Control := Label1;
7878Edit1.Anchors := Edit1.Anchors + [akTop] - [akBottom];
7979```
8080
8181То-же самое может быть сделано с помощью метода:
8282
8383``` pascal
8484Edit1.AnchorVerticalCenterTo(Label1);
8585```
8686
8787Очевидно, что привязка нижнего края Edit1 не имеет смысла при центрировании.
8888
8989# Новое свойство
9090
9191``` pascal
9292property AnchorSide[Kind: TAnchorKind]: TAnchorSide read GetAnchorSide;
9393```
9494
9595Это свойство не опубликовано в [[IDE Window: Object Inspector|инспекторе объектов]]. Вы можете редактировать его в дизайнере с помощью [[IDE Window: Anchor Editor|редактора якорей]]\
9696(меню **View -\> View anchor editor** или щелчок на кнопке свойства **Anchors**).
9797
9898# Новые методы для лёгкого конфигурирования общего расположения
9999
100100``` pascal
101101procedure AnchorToNeighbour(Side: TAnchorKind; Space: integer;
102102 Sibling: TControl);
103103procedure AnchorParallel(Side: TAnchorKind; Space: integer;
104104 Sibling: TControl);
105105procedure AnchorHorizontalCenterTo(Sibling: TControl);
106106procedure AnchorVerticalCenterTo(Sibling: TControl);
107107procedure AnchorAsAlign(TheAlign: TAlign; Space: Integer);
108108```
109109
110110**AnchorVerticalCenterTo** работает также с **Parent**. Тогда центрирование будет происходить по клиентской области, это означает, что центр элемента управления будет в *ClientHeight div 2*.
111111
112112Привязка по центру пока не полностью поддерживается при вычислении размера родителя. Например, когда вы помещаете привязанную по центру метку в Groupbox1 и устанавливаете Groupbox1.AutoSize в True, то высота Groupbox1 будет уменьшаться, не оставляя места для метки. Решение состоит в центрировании по элементу, который не центрирован. Например, центрируйте Label1 по ComboBox и используйте для ComboBox якоря по умолчанию (Anchors=\[akLeft,akTop\]).
113113
114114# Привязка к невидимым элементам управления
115115
116116Начиная с 0.9.25 rev 12800 привязка к невидимым элементам управления была изменена, чтобы работать более интуитивно. Например, ниже элементы управления A, B, C привязаны (C.Left к B.Right и B.Left к A.Right):
117117
118-```
118+```text
119119 +---+ +---+ +---+
120120 | A | | B | | C |
121121 +---+ +---+ +---+
122122```
123123
124124Если B скрыт (Visible:=false), то C.Left будет пропускать B и использовать правый край A, в результате получим следующее:
125125
126-```
126+```text
127127 +---+ +---+
128128 | A | | C |
129129 +---+ +---+
130130```
131131
132132# Циклические ссылки
133133
134134Вы можете создать циклические ссылки, привязав два края друг к другу, что создаёт невозможную привязку. LCL замечает это, но не генерирует исключения, поскольку этот цикл может быть времнным. Например, ряд кнопок: Button1 слева от Button2, Button2 слева от Button3. Теперь меняем порядок на следующий: Button3, Button1, Button2. Если перепривязка начата с Button3, временно создаётся цикл, который исправляется по завершению переупорядочивания. LCL обнаруживает цикл и не перемещает Button. Циклы - не единственная аномалия.
135135
136136Есть одно исключение из этого правила. Если **Parent.AutoSize** установлено в True, то LCL будет автоматически разрывать циклы на autosize и писать предупреждение через **debugln** (windows: --debug-log.txt, linux, et al: stdout). Которая из привязок будет нарушена, зависит от порядка элементов управления и сторон. Таким образом, временные циклы остаются разрешёнными при AutoSize=true, если вы заключите изменение в:
137137
138138``` pascal
139139Parent.DisableAutosizing;
140140try
141141 // change anchors, aligns, bounds...
142142finally
143143 Parent.EnableAutosizing;
144144end;
145145```
146146
147147Алгоритм AutoSize не только разрушает циклы, но также исправляет несоответствия Align/AnchorSide.
148148
149149# См. также
150150
151151- [[Autosize / Layout]]
152152- [[Example: Anchors. How to reliably align dynamically created controls under changing visibility]]
153153
154154---
155155*From the Free Pascal wiki, page "Anchor Sides/ru", as it stood on 2020-02-09 after a change by GAN, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history