Material.Avalonia — быстрый способ стилизовать под Material Design приложение, написанное на AvaloniaUI — кросс-платформенном XAML фреймворке для .NET.
Примерно с год назад на Хабре уже была статья о нашей библиотеке, однако с этого момента изменилось многое: мы избавились от встроенных тем, переделали стандартные и добавили свои элементы управления.
Сейчас наше демо приложение выглядит вот так:
Начало использования
Сначала установим необходимый Nuget пакет:
dotnet add package Material.Avalonia
После этого изменим файл App.xaml
, если нам нужно стилизовать все приложение. Либо, если нужно изменить оформление только одного окна или другого элемента управления, то вместо Application.Styles
(Application.Resources
) у нас будут Window.Styles
или UserControl.Styles
соответственно.
<Application ...
xmlns:themes="clr-namespace:Material.Styles.Themes;assembly=Material.Styles"
...>
<Application.Resources>
<themes:BundledTheme BaseTheme="Light" PrimaryColor="Teal" SecondaryColor="Amber"/>
</Application.Resources>
<Application.Styles>
<StyleInclude Source="avares://Material.Avalonia/Material.Avalonia.Templates.xaml" />
</Application.Styles>
</Application>
Все, после этого все наше приложение будет использовать стили Material Design.
Однако, не все элементы управления уже стилизованы. Если некоторые из них не работают, то измените Application.Styles
следующим образом:
<Application.Styles>
<StyleInclude Source="avares://Avalonia.Themes.Default/DefaultTheme.xaml"/>
<StyleInclude Source="avares://Avalonia.Themes.Default/Accents/BaseLight.xaml"/>
<StyleInclude Source="avares://Material.Avalonia/Material.Avalonia.Templates.xaml" />
</Application.Styles>
Данное изменение добавит стандартные темы контролов Avalonia "под" темы Material.Avalonia.
Темы
За последние 2 месяца мы полностью переписали темы, и, избавились наконец от предварительно заготовленных наборов тем.
Теперь для настройки темы по умолчанию нужно модифицировать свойства BundledTheme
в App.xaml
.
Базовая тема может быть светлой — Light
, темной — Dark
и наследуемой — Inherit
. Последний вариант будет пытаться получить тему, используемую системой, но в данный момент это еще не реализовано.
BundledTheme
поддерживает задание всех, доступных в Material Design, "стандартных" цветов.
Смена цвета, например на Teal
, из кода происходит подобным образом:
var paletteHelper = new PaletteHelper();
var theme = paletteHelper.GetTheme();
theme.SetPrimaryColor(SwatchHelper.Lookup[(MaterialColor) PrimaryColor.Teal]);
paletteHelper.SetTheme(theme);
Однако, через код можно задать вообще любой пользовательский цвет из RGBA.
Про работу с цветами темы я напишу отдельную статью.
Кастомные контролы
Card
Спецификация на сайте Material Design
Для Card можно менять размер тени используя Attached Property:
<styles:Card assists:ShadowAssist.ShadowDepth="Depth1">
...
</styles:Card>
ColorZone
Цветовая зона позволяет легко переключать цвета фона и переднего плана из выбранной палитры Material Design или пользовательских цветов.
<styles:ColorZone Margin="4" Padding="8" Mode="Accent">Accent</styles:ColorZone>
FloatingButton
<styles:FloatingButton Content="+" />
<styles:FloatingButton Content="My long text" />
Тени
В Avalonia поддержка теней "из коробки" ограничена заданием BoxShadows
для Border
.
Однако уже реализован AttachedProperty ShadowAssist
, который может быть использован для Card
, FloatingButton
и Border
.
Когда для Border
задается ShadowAssist.ShadowDepth
то он самостоятельно корректирует BoxShadows
для соответствия выбранному уровню ShadowDepth.
Так-же есть ShadowAssist.Darken
, позволяющий затемнять уже существующую тень и делающий это с анимацией. Таким образом сделано изменение тени, при наведение на кнопки.
Демонстрация Card с разными ShadowDepth
Многое уже сделано, еще больше — запланировано.
Ознакомиться или помочь с разработкой можно на GitHub
Скачать пакет на NuGet
Issue/PR и просто отзывы категорически приветствуются.
Поддержку от разработчиков Avalonia и всех сочувствующих можно получить в Telegram (ru) и Gitter (en), а документация по стилизации элементов управления доступна тут.
anon12332
а нужен ли AvaloniaUI, если MAUI(.NET Multi-platform App UI) развивается?
github.com/dotnet/maui
WondeRu
Насколько я понимаю, авалониа уже есть, а maui еще только в зачатке.
rstm-sf
MAUI — это, по сути, все тот же Xamarin.Forms. Одно из измнений бросающихся в глаза: поддержка macOS переходит под крыло MS.
Например, то, что хотят использовать компилятор, написанный для Avalonia, рассматривают в использовании для WinUI, говорит в пользу авалонии.
Ну, и можно задуматься над тем, что с помощью авалонии можно задуматься о переносе винформ-приложений на кроссплатформ ;)
mrbaranovskyi
MAUI это Замарин, по сути. Всегда было интересно, почему не хотят в Майкрософт сделать это нативно.
Phrynohyas
По факту это и есть «нативно» (для экосистемы .NET). Xamarin ведь принадлежит MS
egorozh
Учитывая, что MAUI будет основан на обёртках нативных контролов как в Xamarin, я бы всё-таки ставил на AvaloniaUI, где интерфейс полностью рендерится фреймворком как в WPF.
mrbaranovskyi
Да, согласен. Буквально недавно «обнаружил» этот фреймворк. Увы, достаточно сильно он отличается от WPF. Если я правильно понимаю, то концепт стилей сменился достаточно радикально и теперь большее на css. Тяжелые проекты будет тяжко портировать.
egorozh
Тяжело будет портировать в любом случае) Хотя бы из-за отсутствия различных библиотек контролов и приколюх, которые есть для WPF. А к другой организации стилей привыкаешь буквально за пару-тройку дней. Мне вот нравится синтаксис байндингов, когда вместо {Binding Path=Property, RelativeSource{RelativeSource Self}},
пишешь что-то в духе {Binding $self.Property}
mrbaranovskyi
Да, кстати.
И вот, хотя бы, за вот это построю монумент из стаканчиков из под кофе в честь того, кто это заимплементил.
{Binding !AllowInput}"
Миллиарды булеан-конвертеров канут в лета.
SKProCH Автор
Такое реализовывалось для WPF MVVM фреймворком
MugenMVVMToolkit
, который стал для меня незаменим при разработке WPF приложений. Там вообще можно было делать что-то такое и оно будет прекрасно работать:Text $string.Join($Environment.NewLine, $GetErrors())
Я связывался с автором
MugenMVVMToolkit
, он сказал что посмотрит в сторону портирования его для Avalonia.