Sign in Join
Wiki copytemporary

Anchor Sides/ru: what changed

Revision 2 to 3. 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-`+--------+ +-------+`\
8-`| Label1 | | Edit1 |`\
9-`+--------+ |       |`\
10-`           +-------+`
7+```
8++--------+ +-------+
9+| Label1 | | Edit1 |
10++--------+ | |
11+ +-------+
12+```
1113
1214## В коде
1315
1416``` pascal
1517Edit1.AnchorSide[akLeft].Side := asrRight;
1618Edit1.AnchorSide[akLeft].Control := Label1;
1719Edit1.Anchors := Edit1.Anchors + [akLeft];
1820```
1921
2022Вы можете задать расстояние с помощью свойств BorderSpacing:
2123
2224``` pascal
2325Edit1.BorderSpacing.Left := 10;
2426```
2527
2628То-же самое может быть сделано с помощью метода:
2729
2830``` pascal
2931Edit1.AnchorToNeighbour(akLeft, 10, Label1);
3032```
3133
3234## Примечания
3335
3436**Edit1.Left** будет следовать за **Label1.Left+Label1.Width**, но не наоборот. Это означает, что перемещение Label1 будет вызывать перемещение Edit1. Но перемещение Edit1 будет отменяться LCL. Если вы также привяжете правую сторону Label1 к левой стороне Edit1, вы создадите кольцо и в сочетании с некоторыми другими свойствами авторазмера это приведёт к циклу. Это игнорируется LCL или автоматически исправляется, когда Parent.AutoSize установлено в True.
3537
3638## С помощью редактора якорей
3739
3840Редактор якорей - плавающее окно, доступное через меню **View / Anchor Editor** или через кнопку в свойстве **Anchors** в инспекторе объектов.
3941
4042![](/wiki-images/6/6d/Anchoreditor.png)
4143
4244# Пример 2
4345
4446Вы можете привязать верхний край Edit для следования за верхним краем Label:
4547
4648 +--------+ +-------+
4749 | Label1 | | Edit1 |
4850 +--------+ | |
4951 +-------+
5052
5153``` pascal
5254Edit1.AnchorSide[akTop].Side := asrTop;
5355Edit1.AnchorSide[akTop].Control := Label1;
5456Edit1.Anchors := Edit1.Anchors + [akTop];
5557```
5658
5759То-же самое может быть сделано с помощью метода:
5860
5961``` pascal
6062Edit1.AnchorParallel(akTop,0,Label1);
6163```
6264
6365# Пример 3
6466
6567Вертикальное центрирование Edit относительно Label:
6668
6769 +-------+
6870 +--------+ | |
6971 | Label1 | | Edit1 |
7072 +--------+ | |
7173 +-------+
7274
7375``` pascal
7476Edit1.AnchorSide[akTop].Side := asrCenter;
7577Edit1.AnchorSide[akTop].Control := Label1;
7678Edit1.Anchors := Edit1.Anchors + [akTop] - [akBottom];
7779```
7880
7981То-же самое может быть сделано с помощью метода:
8082
8183``` pascal
8284Edit1.AnchorVerticalCenterTo(Label1);
8385```
8486
8587Очевидно, что привязка нижнего края Edit1 не имеет смысла при центрировании.
8688
8789# Новое свойство
8890
8991``` pascal
9092property AnchorSide[Kind: TAnchorKind]: TAnchorSide read GetAnchorSide;
9193```
9294
9395Это свойство не опубликовано в [[IDE Window: Object Inspector|инспекторе объектов]]. Вы можете редактировать его в дизайнере с помощью [[IDE Window: Anchor Editor|редактора якорей]]\
9496(меню **View -\> View anchor editor** или щелчок на кнопке свойства **Anchors**).
9597
9698# Новые методы для лёгкого конфигурирования общего расположения
9799
98100``` pascal
99101procedure AnchorToNeighbour(Side: TAnchorKind; Space: integer;
100102 Sibling: TControl);
101103procedure AnchorParallel(Side: TAnchorKind; Space: integer;
102104 Sibling: TControl);
103105procedure AnchorHorizontalCenterTo(Sibling: TControl);
104106procedure AnchorVerticalCenterTo(Sibling: TControl);
105107procedure AnchorAsAlign(TheAlign: TAlign; Space: Integer);
106108```
107109
108110**AnchorVerticalCenterTo** работает также с **Parent**. Тогда центрирование будет происходить по клиентской области, это означает, что центр элемента управления будет в *ClientHeight div 2*.
109111
110112Привязка по центру пока не полностью поддерживается при вычислении размера родителя. Например, когда вы помещаете привязанную по центру метку в Groupbox1 и устанавливаете Groupbox1.AutoSize в True, то высота Groupbox1 будет уменьшаться, не оставляя места для метки. Решение состоит в центрировании по элементу, который не центрирован. Например, центрируйте Label1 по ComboBox и используйте для ComboBox якоря по умолчанию (Anchors=\[akLeft,akTop\]).
111113
112114# Привязка к невидимым элементам управления
113115
114116Начиная с 0.9.25 rev 12800 привязка к невидимым элементам управления была изменена, чтобы работать более интуитивно. Например, ниже элементы управления A, B, C привязаны (C.Left к B.Right и B.Left к A.Right):
115117
116-` +---+ +---+ +---+`\
117-` | A | | B | | C |`\
118-` +---+ +---+ +---+`
118+```
119+ +---+ +---+ +---+
120+ | A | | B | | C |
121+ +---+ +---+ +---+
122+```
119123
120124Если B скрыт (Visible:=false), то C.Left будет пропускать B и использовать правый край A, в результате получим следующее:
121125
122-` +---+ +---+`\
123-` | A | | C |`\
124-` +---+ +---+`
126+```
127+ +---+ +---+
128+ | A | | C |
129+ +---+ +---+
130+```
125131
126132# Циклические ссылки
127133
128134Вы можете создать циклические ссылки, привязав два края друг к другу, что создаёт невозможную привязку. LCL замечает это, но не генерирует исключения, поскольку этот цикл может быть времнным. Например, ряд кнопок: Button1 слева от Button2, Button2 слева от Button3. Теперь меняем порядок на следующий: Button3, Button1, Button2. Если перепривязка начата с Button3, временно создаётся цикл, который исправляется по завершению переупорядочивания. LCL обнаруживает цикл и не перемещает Button. Циклы - не единственная аномалия.
129135
130136Есть одно исключение из этого правила. Если **Parent.AutoSize** установлено в True, то LCL будет автоматически разрывать циклы на autosize и писать предупреждение через **debugln** (windows: --debug-log.txt, linux, et al: stdout). Которая из привязок будет нарушена, зависит от порядка элементов управления и сторон. Таким образом, временные циклы остаются разрешёнными при AutoSize=true, если вы заключите изменение в:
131137
132138``` pascal
133139Parent.DisableAutosizing;
134140try
135141 // change anchors, aligns, bounds...
136142finally
137143 Parent.EnableAutosizing;
138144end;
139145```
140146
141147Алгоритм AutoSize не только разрушает циклы, но также исправляет несоответствия Align/AnchorSide.
142148
143149# См. также
144150
145151- [[Autosize / Layout]]
146152- [[Example: Anchors. How to reliably align dynamically created controls under changing visibility]]
147153
148154---
149155*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