Sign in Join
Wiki copytemporary

Anchor Sides/ru: what changed

Revision 1 to 2. 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
77`+--------+ +-------+`\
88`| Label1 | | Edit1 |`\
99`+--------+ |       |`\
1010`           +-------+`
1111
1212## В коде
1313
1414``` pascal
1515Edit1.AnchorSide[akLeft].Side := asrRight;
1616Edit1.AnchorSide[akLeft].Control := Label1;
1717Edit1.Anchors := Edit1.Anchors + [akLeft];
1818```
1919
2020Вы можете задать расстояние с помощью свойств BorderSpacing:
2121
2222``` pascal
2323Edit1.BorderSpacing.Left := 10;
2424```
2525
2626То-же самое может быть сделано с помощью метода:
2727
2828``` pascal
2929Edit1.AnchorToNeighbour(akLeft, 10, Label1);
3030```
3131
3232## Примечания
3333
3434**Edit1.Left** будет следовать за **Label1.Left+Label1.Width**, но не наоборот. Это означает, что перемещение Label1 будет вызывать перемещение Edit1. Но перемещение Edit1 будет отменяться LCL. Если вы также привяжете правую сторону Label1 к левой стороне Edit1, вы создадите кольцо и в сочетании с некоторыми другими свойствами авторазмера это приведёт к циклу. Это игнорируется LCL или автоматически исправляется, когда Parent.AutoSize установлено в True.
3535
3636## С помощью редактора якорей
3737
3838Редактор якорей - плавающее окно, доступное через меню **View / Anchor Editor** или через кнопку в свойстве **Anchors** в инспекторе объектов.
3939
40-<figure>
41-<img src="Anchoreditor.png" title="Anchoreditor.png" />
42-<figcaption>Anchoreditor.png</figcaption>
43-</figure>
40+![](/wiki-images/6/6d/Anchoreditor.png)
4441
4542# Пример 2
4643
4744Вы можете привязать верхний край Edit для следования за верхним краем Label:
4845
4946 +--------+ +-------+
5047 | Label1 | | Edit1 |
5148 +--------+ | |
5249 +-------+
5350
5451``` pascal
5552Edit1.AnchorSide[akTop].Side := asrTop;
5653Edit1.AnchorSide[akTop].Control := Label1;
5754Edit1.Anchors := Edit1.Anchors + [akTop];
5855```
5956
6057То-же самое может быть сделано с помощью метода:
6158
6259``` pascal
6360Edit1.AnchorParallel(akTop,0,Label1);
6461```
6562
6663# Пример 3
6764
6865Вертикальное центрирование Edit относительно Label:
6966
7067 +-------+
7168 +--------+ | |
7269 | Label1 | | Edit1 |
7370 +--------+ | |
7471 +-------+
7572
7673``` pascal
7774Edit1.AnchorSide[akTop].Side := asrCenter;
7875Edit1.AnchorSide[akTop].Control := Label1;
7976Edit1.Anchors := Edit1.Anchors + [akTop] - [akBottom];
8077```
8178
8279То-же самое может быть сделано с помощью метода:
8380
8481``` pascal
8582Edit1.AnchorVerticalCenterTo(Label1);
8683```
8784
8885Очевидно, что привязка нижнего края Edit1 не имеет смысла при центрировании.
8986
9087# Новое свойство
9188
9289``` pascal
9390property AnchorSide[Kind: TAnchorKind]: TAnchorSide read GetAnchorSide;
9491```
9592
9693Это свойство не опубликовано в [[IDE Window: Object Inspector|инспекторе объектов]]. Вы можете редактировать его в дизайнере с помощью [[IDE Window: Anchor Editor|редактора якорей]]\
9794(меню **View -\> View anchor editor** или щелчок на кнопке свойства **Anchors**).
9895
9996# Новые методы для лёгкого конфигурирования общего расположения
10097
10198``` pascal
10299procedure AnchorToNeighbour(Side: TAnchorKind; Space: integer;
103100 Sibling: TControl);
104101procedure AnchorParallel(Side: TAnchorKind; Space: integer;
105102 Sibling: TControl);
106103procedure AnchorHorizontalCenterTo(Sibling: TControl);
107104procedure AnchorVerticalCenterTo(Sibling: TControl);
108105procedure AnchorAsAlign(TheAlign: TAlign; Space: Integer);
109106```
110107
111108**AnchorVerticalCenterTo** работает также с **Parent**. Тогда центрирование будет происходить по клиентской области, это означает, что центр элемента управления будет в *ClientHeight div 2*.
112109
113110Привязка по центру пока не полностью поддерживается при вычислении размера родителя. Например, когда вы помещаете привязанную по центру метку в Groupbox1 и устанавливаете Groupbox1.AutoSize в True, то высота Groupbox1 будет уменьшаться, не оставляя места для метки. Решение состоит в центрировании по элементу, который не центрирован. Например, центрируйте Label1 по ComboBox и используйте для ComboBox якоря по умолчанию (Anchors=\[akLeft,akTop\]).
114111
115112# Привязка к невидимым элементам управления
116113
117114Начиная с 0.9.25 rev 12800 привязка к невидимым элементам управления была изменена, чтобы работать более интуитивно. Например, ниже элементы управления A, B, C привязаны (C.Left к B.Right и B.Left к A.Right):
118115
119116` +---+ +---+ +---+`\
120117` | A | | B | | C |`\
121118` +---+ +---+ +---+`
122119
123120Если B скрыт (Visible:=false), то C.Left будет пропускать B и использовать правый край A, в результате получим следующее:
124121
125122` +---+ +---+`\
126123` | A | | C |`\
127124` +---+ +---+`
128125
129126# Циклические ссылки
130127
131128Вы можете создать циклические ссылки, привязав два края друг к другу, что создаёт невозможную привязку. LCL замечает это, но не генерирует исключения, поскольку этот цикл может быть времнным. Например, ряд кнопок: Button1 слева от Button2, Button2 слева от Button3. Теперь меняем порядок на следующий: Button3, Button1, Button2. Если перепривязка начата с Button3, временно создаётся цикл, который исправляется по завершению переупорядочивания. LCL обнаруживает цикл и не перемещает Button. Циклы - не единственная аномалия.
132129
133130Есть одно исключение из этого правила. Если **Parent.AutoSize** установлено в True, то LCL будет автоматически разрывать циклы на autosize и писать предупреждение через **debugln** (windows: --debug-log.txt, linux, et al: stdout). Которая из привязок будет нарушена, зависит от порядка элементов управления и сторон. Таким образом, временные циклы остаются разрешёнными при AutoSize=true, если вы заключите изменение в:
134131
135132``` pascal
136133Parent.DisableAutosizing;
137134try
138135 // change anchors, aligns, bounds...
139136finally
140137 Parent.EnableAutosizing;
141138end;
142139```
143140
144141Алгоритм AutoSize не только разрушает циклы, но также исправляет несоответствия Align/AnchorSide.
145142
146143# См. также
147144
148145- [[Autosize / Layout]]
149146- [[Example: Anchors. How to reliably align dynamically created controls under changing visibility]]
150147
151148---
152149*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