AvaloniaUI: особенности на примере MessageBox

  • Tutorial
Avalonia ui — восхитительный фреймворк, к которому хочется возвращаться снова и снова. Так давайте же вернемся к нему еще раз и рассмотрим некоторые особенности вместе с моим message box.



Кто же такая Авалония


Avalonia — это кросплатформенный фреймворк, позволяющий разрабатывать графические интерфейсы на всех актуальных платформах.

По своей структуре он невероятно близок к wpf: похожий xaml, похожие биндинги. Даже есть официальный туториал для разработчиков wpf.

Примечательна же авалония тем, что на каждой из систем она обращается к родным интерфейсам: Win32, MonoMac, X11…

Что же появилось в обновленной версии
  1. Поддержка 13 различных иконок сообщений.
  2. Возможность копирования тела сообщения при помощи комбинации клавиш Cntrl+C.
  3. Подстраивание размера окна под его содержимое.
  4. Упрощенная система стилей, что позволяет желающим легко включится в разработку и поддержку новых.
  5. Замена TextBlock на TextBox, теперь текст в окне можно выделять.
  6. Полностью переработана сама архитектура.



С документацией можно ознакомится на gitlab.

Сам же пакет можно скачать с nuget.

Поговорим же про особенности и фишки avalonia


Очевидно, что если будут сравнения, то сравниваться будет с wpf.

Первое, что бросается в глаза после фреймворков от ms, это возможность биндить команды к методам. Да, функционально это дает меньше возможностей, но в ответ упрощает подход к разработке view model.

<Button Command="{Binding RunTheThing}" CommandParameter="Hello World">
Do the thing!
</Button>

public void RunTheThing(string parameter)
{
            // Code for executing the command here.
}

Также Авалония построена с помощью реактивных расширений, что позволяет работать с событиями фреймворка как с объектами первого класса с помощью декларативного синтаксиса запросов LINQ — позволяя писать лаконичный и читаемый код.

Но уходя чуть вглубь, все становится не столь радужно и очевидно, да и документация пока что еще не доведена до ума (но вы можете помочь).

Биндинг к image


Проблема, с которой я встретился почти сразу же при обновлении своего проекта,- как отобразить изображения на моем окне.

Для начала стоит нужно зарегистрировать директорию с изображениями как ресурс авалонии, ведь важно, чтобы иконки отобразились у любого пользователя и удобно упаковывались вместе со всем кодом.

 <ItemGroup>
        ...
        <AvaloniaResource Include="Assets\*" />
</ItemGroup>

Теперь в тэге image можно легко устанавливать выбранное изображение.

<Image  Source="/Assets/error.ico" />

Но при использовании vm Source изображения нельзя просто прибиндить к string, а необходимо использовать Bitmap.

<Image   Source="{Binding ImagePath}" />

 public Bitmap ImagePath { get; private set; }

И соответсвенно теперь нужно извлечь наше изображение из ресурсов. Для чего нужно использовать локатор авалонии.

ImagePath = new Bitmap(AvaloniaLocator.Current.GetService<IAssetLoader>()
                    .Open(new Uri($" avares://ASSEMBLYNAME/relative/project/path/{ImageName}.ico")));

Стоит отметить, что для embedded ресурсов при составлении uri используется приставка resm://, а для avalonia — avares://.

Рисование


Фигуры в avalonia и wpf схожи, но публичные свойства отличаюся. Поэтому, скачивая svg изображения и преобразуя с помощью inskape их в ms xaml, ими нельзя было сразу воспьзоваться.

Произвольная фигура

<PathGeometry 
Figures="M30 53  C15.641 53 4 41.359 4 27S15.641 1 30 1s26 11.641 26 26c0 7.135-2.874 13.599-7.528 18.297" 
FillRule="NonZero"/>

Превращается в:

<GeometryDrawing 
Brush="#FF50C8EF" 
Geometry="M30 53  C15.641 53 4 41.359 4 27S15.641 1 30 1s26 11.641 26 26c0 7.135-2.874 13.599-7.528 18.297"   />

А линия:

<Line  X1="25" Y1="37" 
X2="25" Y2="39" StrokeThickness="2" 
Stroke="#FFFFFFFF" 
StrokeMiterLimit="10" 
StrokeStartLineCap="Round" 
StrokeEndLineCap="Round"/>

Превращается в:

<Line   
StartPoint="25,37" 
EndPoint="25,39"  
StrokeThickness="2" 
Stroke="#FFFFFFFF"  
StrokeStartLineCap="Round" 
StrokeEndLineCap="Round"/>

Стили


Про сами стили достаточно сказано в документации. Стоит лишь отметить, что это привычные стили с небольшой примесью css. Я же хотел показать, как применить стиль из отдельного файла. Во-первых все xaml файлы должны являться ресурсами авалонии.

<ItemGroup>
        <AvaloniaResource Include="**\*.xaml">
            <SubType>Designer</SubType>
        </AvaloniaResource>
      .....
    </ItemGroup>

Во-вторых, стили применяются так же, как и ресурсы изображений при помощи uri и локатора.

YourControl.Styles.Add(new StyleInclude(new Uri("avares://ASSEMBLYNAME/relative/project/path.xaml")){Source = new Uri("avares://ASSEMBLYNAME/relative/project/path.xaml")});

Приятные мелочи


У TextBox присутствует свойство Watermark. Что позволяет не искать сторонние пакеты и не городить TextBlock поверх TextBox, что можно прочитать во многих туториалах для wpf.

<TextBox Watermark="Street address" />

А также весь биндинг по умолчанию использует PropertyChanged для триггера обновления связанного свойства.

В заключение


Предлагаю всем попробовать этот интересный фреймворк. Выражаю благодарность пользователям Artyom Gorchakov и Никита Цуканов.

И напоминаю, что у avalonia есть уютная и восхитительная поддержка в Gitter.
Share post

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 17

    0

    Спасибо, попробую! А планируется ли включить MessageBox в сам ферймворк или он так и будет поставляться отдельно?

      0
      С этим есть определенные проблемы на текущий момент, я слышал, что у заработчика kekekeks были планы, по созданию чего-то подобного
      т.к. мое решение не способно работать на android и ios, а авалония метит на все платформы, то в проект, я полагаю, должны быть включены универсальне решения.
      Пока так, потом ждем новостей от авторов, если им что-то понравится, я готов целиком отдать решение.

      Да и стоит еще добавить много фич, потому как платформы разные и как бы мне не хотелось, но все еще мои окна сообщений все же по разному ведут себя, но я над этим работаю
        +2

        Чтобы его поставить в сам фреймворк, его нужно нормально сделать. В понятие "нормально" входит "кроссплатформенно". Те же мобильные платформы работают несколько иначе чем десктопные, да и пользователю лучше работать в этом плане с нативным интерфейсом. Так что как минимум необходимо задейтствовать NSAlert, UIAlert и AlertDialog, а апи самого мессаджбокса сделать таким, чтобы оно отражало и их особенности. До всего этого должны дойти руки.

        0
        А на сколько AvaloniaUI стала актуальна, с выходом .NET Core 3 и возможностью создания кроссплатформерных приложений с WPF? AvaloniaUI по прежнему будет развиваться? И если да, то почему?
          +3
          возможностью создания кроссплатформерных приложений с WPF

          Вообще-то такой возможности нет и не планируется вообще.

            0
            Но я же могу запустить сейчас WPF проект на macos/linux/windows.
            docs.microsoft.com/en-us/dotnet/core/whats-new/dotnet-core-3-0
            Или чего-то не понимаю?
              0
              нет, вы чего-то не понимаете, dotnet отлично живет уже очень давно на разных системах, но вот wpf framework осуществляет много вызовов привязанных к платформе windows таких как обращения к win32 user32 и что самое главное к dx9

              хотя как указано вот тут есть шанс, что комьюнити что-нибудь вкостылит
                +3

                Вообще говоря не можете. Только Windows. Портировать не собираются. Все попытки добавить кроссплатформенность (даже чтобы можно было просто собрать WPF-проекты на никсах жёстко пресекаются.

                  0

                  Интересно, почему пресекаются, да еще и жестко?

                    0

                    Потому что это никоим образом не входит в круг целей майнтейнеров.


                    По майнтернерами имеется в виду люди, тратящие время и средства на развитие проекта.


                    Чисто по человечески — это настолько непочатый край работы, на каждом этапе способный поломать стабильные части (тдл там и не пахнет), что в здравом уме этим заниматься никто не будет

                      0

                      А я думал это в большей степени от топов зависят: по экономическим или еще каким-то причинам не хотят WPF приложения на линуксе.

            0
            Первое, что бросается в глаза после фреймворков от ms, это возможность биндить команды к методам

            Так я в Сильверлайте еще 8 лет назад так делал:
            <Button Source={StaticResource PersRegResource}}" Command="{Binding Path=ShowExecMonitoringCommand}"></Button>

            и в модели:
            private ICommandRaiser _fieldShowExecMonitoringCommand;
             public ICommandRaiser ShowExecMonitoringCommand
             {
               get
                {
                  return _fieldShowExecMonitoringCommand ??
                     (_fieldShowExecMonitoringCommand = new 
                         RelayCommand(ExecuteShowExecMonitoringCommand,
                                                                                       CanExecuteShowExecMonitoringCommand));
                 }
              }
            
              private bool CanExecuteShowExecMonitoringCommand(object parameter)
              {
                 return SelectedMoContract != null;
              }
              private void ExecuteShowExecMonitoringCommand(object parameter)
              {
                   // code here
              }
            

            причем CanExecuteShowExecMonitoringCommand автоматически управляла доступностью кнопки
              0
              Биндить команды к объектам, унаследованным от ICommand, или к ReactiveCommand конечно предпочтительнее, управление доступностью кнопки тоже здорово, но avalonia позволяет сделать вот так
              <Button Command="{Binding RunTheThing}" CommandParameter="Hello World">Do the thing!</Button>

               public class MainWindowViewModel : ViewModelBase
                  {
                      public void RunTheThing(string parameter)
                      {
                          // Code for executing the command here.
                      }
                  }
                0
                Прошу прощения, неправильно понял Ваш посыл. Думал имеется ввиду, что вообще нельзя во фрэймворках от MS биндить к командам. А так да, в некоторых случаях нет смысла городить приведенную мной конструкцию, а проще напрямую прибиндить к методу
              0
              Что-то название ассоциируется с кодовым названием Windows Presentation Foundation времен Longhorn — Avalon.
                0

                Это, конечно, здорово, но фреймворк всё ещё сырой, помню тоже пытался на нем что-то клепать. В общем, пилить и пилить.

                  –1

                  С 8й версией вышел в бетту, если посмотрите статьи автора уже есть определенный пул приложений, построенных на нем

                Only users with full accounts can post comments. Log in, please.