Размеры: расширение SizeExtension¶
Для использования необходимо подключить nuget-пакет ModPlusStyle версии не ниже 16.0 (если в пакете модуля версия ниже)!
<PackageReference Include="ModPlusStyle" Version="16.0.0" ExcludeAssets="runtime" />
Назначение¶
SizeExtension — разметочное расширение {mps:Size}, которое задаёт размер, автоматически
уменьшающийся в компактном режиме библиотеки оформления.
Компактный режим (ThemeManager.IsCompactMode, начальное значение — параметр CompactMode
в реестре HKCU\Software\ModPlus) уменьшает отступы и высоты элементов внутри самих стилей.
Но размеры, которые плагин задаёт сам — ширина поля ввода, ширина колонки, максимальная ширина
окна — библиотека не видит. Если написать Width="170", поле останется шириной 170 пикселей
и в компактном режиме, и вся экономия места пропадёт. {mps:Size 170} решает эту задачу.
Отступы этим расширением не задают. Для них есть
{mps:Margin}с множителями базовой единицы — см. Отступы: ресурсы Margin и расширение MarginExtension.
Подключение¶
Как считается значение¶
Число в расширении — это размер в пикселях для обычного режима. В компактном режиме он
умножается на коэффициент из ресурса ModPlus.Sizes.Scale и округляется до целого пикселя
(округление от нуля, то есть 127.5 → 128).
| Ресурс | Обычный режим | Компактный режим |
|---|---|---|
ModPlus.Sizes.Scale |
1.0 |
0.75 |
Примеры:
| Запись | Обычный режим | Компактный режим |
|---|---|---|
{mps:Size 170} |
170 |
128 |
{mps:Size 200} |
200 |
150 |
{mps:Size 240} |
240 |
180 |
{mps:Size 300} |
300 |
225 |
{mps:Size 1000} |
1000 |
750 |
Нижняя граница¶
Второе число, если оно указано, — нижняя граница: ниже неё размер не опускается, каким бы плотным ни был режим. Пригодится там, где слишком узкое поле перестаёт быть читаемым: поле для номера листа, колонка с датой, кнопка с длинной подписью.
| Запись | Обычный режим | Компактный режим |
|---|---|---|
{mps:Size 170} |
170 |
128 |
{mps:Size 170, 150} |
170 |
150 — сработала нижняя граница |
Обратите внимание на синтаксис: два числа передаются через запятую и без кавычек —
это два аргумента конструктора расширения, а не одна строка (в отличие от {mps:Margin '1 0.5'},
где вся запись множителей берётся в кавычки).
Значение 0 (и отсутствие второго аргумента) означает «без ограничения». Свойства расширения
можно задавать и по именам:
Каким свойствам подходит¶
Расширение возвращает double, поэтому подходит любому свойству этого типа:
Width,HeightMinWidth,MinHeightMaxWidth,MaxHeight- любому пользовательскому свойству типа
double
Отдельный случай — ColumnDefinition.Width и RowDefinition.Height: они имеют тип
GridLength, и расширение само отдаёт значение как GridLength в пикселях.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{mps:Size 200}" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
</Grid>
Смешанный вариант — колонка тянется, но не сжимается меньше заданного:
Пример: окно плагина¶
<mps:ModPlusWindow x:Class="MyPlugin.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mps="https://modplus.org/winfx/xaml/controls"
Title="Нумерация помещений"
Width="{mps:Size 1000}"
Height="{mps:Size 640}"
MinWidth="{mps:Size 760}"
MinHeight="{mps:Size 480}">
<StackPanel Margin="{mps:Margin 1}">
<TextBox Width="{mps:Size 170}"
HorizontalAlignment="Left" />
<!-- Поле не должно становиться уже 150: иначе не видно значение целиком -->
<mps:NumericBox Width="{mps:Size 170, 150}"
HorizontalAlignment="Left" />
<TextBlock MaxWidth="{mps:Size 364}"
TextWrapping="Wrap"
Text="Длинное пояснение, которое не должно растягиваться на всю ширину окна." />
</StackPanel>
</mps:ModPlusWindow>
Размеры для контролов, создаваемых в коде¶
Если контрол собирается в C#, вместо присваивания числа используйте DensityAssist.SetSize:
using ModPlusStyle.Controls;
var textBox = new TextBox();
// Width = 170 в обычном режиме, 128 в компактном
DensityAssist.SetSize(textBox, FrameworkElement.WidthProperty, 170);
// То же самое, но не уже 150
DensityAssist.SetSize(textBox, FrameworkElement.WidthProperty, 170, 150);
Метод ставит привязку, а не константу, поэтому значение пересчитывается при переключении режима на лету.
Технические детали¶
- Значение отдаётся привязкой к наследуемому свойству
DensityAssist.Scale, поэтому оно следует за ресурсомModPlus.Sizes.Scaleи переживает переключение компактного режима без перезагрузки окна. ModPlusWindowв конструкторе связываетDensityAssist.Scaleс этим ресурсом, и значение наследуется всеми элементами внутри окна.- Когда цель расширения известна, оно дополнительно ставит ссылку на ресурс само — как для
FrameworkElement, так и дляFrameworkContentElement. Благодаря этому{mps:Size}работает и в окнах, не унаследованных отModPlusWindow, — достаточно, чтобы были подключены словари стилей. - Если ни того, ни другого нет, коэффициент берёт значение по умолчанию
1, то есть размер остаётся таким, как в обычном режиме.
Чего расширение не делает¶
- Не задаёт отступы. Для них —
{mps:Margin}. - Не масштабирует размеры самих контролов библиотеки. Высоты полей, паддинги кнопок,
высоты строк меню уменьшаются словарём
Density.Compact.xamlвнутри стилей — их задавать вручную не нужно. - Не трогает иконки и геометрию глифов. В компактном режиме они намеренно оставлены прежними: их уменьшение ломает отрисовку, а не делает интерфейс плотнее. Если задаёте размер иконки, оставляйте обычное число.
- Не уменьшает текст подсказок и заголовков столбцов
DataGrid. РесурсыModPlus.Fonts.Sizes.TooltipиModPlus.Fonts.Sizes.DataGridColumnHeader(оба12) в компактном режиме намеренно оставлены прежними: они равны базовому размеру текстаModPlus.Fonts.Sizes.Content, который компактный режим не трогает, а подсказка или заголовок мельче поясняемого текста читаются плохо.
Размер и положение окна¶
Начиная с версии 16.0.8 ModPlusWindow с включённым SaveWindowPosition запоминает размер
и положение отдельно для каждого режима: в компактном режиме к ключу хранилища (полному имени
типа окна) добавляется суффикс .Compact. Содержимое при разной плотности занимает разное
место, и один общий размер подходил бы только одному из режимов.
- Ключ выбирается при открытии окна. Если переключить компактный режим у уже открытого окна, при закрытии размер сохранится туда же, откуда был загружен.
- После обновления пакета окно при первом открытии в компактном режиме откроется с размером по умолчанию — ранее сохранённый размер относится к обычному режиму.
- Поэтому в разметке окна не нужно подбирать
Width/Height, которые устроят оба режима: достаточно{mps:Size}для начального размера, дальше пользователь настроит окно сам.
Высота пунктов меню¶
Начиная с версии 16.0.9 высота пунктов Menu/ContextMenu задаётся через MinHeight,
а не Height (ресурсы ModPlus.Sizes.MenuItem.Height и ModPlus.Sizes.MenuItem.TopLevelHeight).
Пункт с крупным или многострочным заголовком теперь растёт по содержимому и не обрезается
в компактном режиме. Если нужен пункт фиксированной высоты, задавайте Height явно.