Aero Framework — передовая библиотека для промышленной и индивидуальной разработки кросс-платформенных XAML-ориентированных приложений с применением концепций MVVM-проектирования. Её основные достоинства — интуитивная ясность, предельная лаконичность, минималистичность и высокое быстродействие.
С версии 2.0 она стала платной для коммерческого использования, но остаётся свободной для учебных целей и проектов с открытым исходным кодом. Стоимость лицензии составляет 30$ на одного разработчика.
Вложив небольшую сумму денег и день-два в углубленное изучение её особенностей, вы сохраните недели и месяцы труда на реальных проектах. Более того, даже если вы опытный разработчик, значительно повысите свой технический уровень, архитектурные навыки и системность мышления. В данный момент всё зависит лишь от вашей усидчивости и трудолюбия. Гарантирую, что оно того стоит.

Первым делом нужно загрузить библиотеку с официального сайта или альтернативных источников:
сайт,
dropbox,
onedrive,
google.drive, — после чего распаковать архив и открыть тестовые проекты HelloAero, BankOnline, Sparrow, — они помогут быстрее войти в курс дела и послужат живыми примерами.
Следует отметить, что библиотека достаточно легко внедряется в уже существующие решения, поэтому буквально сразу может быть использована в деле. Итак, рассмотрим что же в ней примечательного на первый взгляд.
1) Эвокаторы Свойств и Команд (Property and Command Evocators)
Чтобы подписаться на событие уведомления об изменении значения свойства вместо классической конструкции
достаточно использовать более лаконичный вариант на основе лямбда выражений
Парсинг выражения выполняется лишь единожды при инициализации, поэтому на производительность это не оказывает существенного влияния, но делает код намного более линейным и читаемым.
Обработчики для маршрутизируемых и контекстных команд задаются схожим образом.
Контекстные команды — кросс-платформенная и безопасная от утечек памяти реализация команд, отдалённо напоминающая логику работы маршрутизируемых команд в WPF.
2) Равноправные Инжекции путём Экспанирования (Equitable Injections via Exposable Way)
Классические инжекции зависимостей в конструктор вью-моделей не самая лучшая практика. Да, существует множество контейнеров, реализующих такую функциональность и распространён такой подход повсеместно, но он обладает целым рядом недостатков и накладывает большие ограничения на проектируемую систему. Об этом можно долго говорить, поэтому сейчас обозначим лишь суть проблемы: инжекции в конструктор создают иерархические зависимости, то есть при возникновении необходимости добраться из низкоуровневой вью-модели к высокоуровневой без сомнительных решений нельзя. Однако существует способ прямых инжекции вью-моделей без создания иерархических зависимостей, сохраняющий их равноправность! Это очень важное свойство для сериализации и десереализации замкнутых графов объектов, что оставляет возможность для полного сохранения и восстановления логического и визуалного состояний всего приложения при его перезагрузке.
Реализуется подобное очень просто и естественно. Посмотрите пример кода в проекте HelloAero в разделе Exposable.
3) Умное Состояние и Умные Свойства (Smart State & Smart Properties)
В языке JavaScript реализована очень мощная концепция слаботипизированных свойств, а также встроенные возможности простой сериализации и десериализации объектов, что делает его незаменимым при разработке сложных динамических интерфейсов. Отчасти эти концепции нашли отражение в механизмах Smart State и Smart Properties.
Взгляните, насколько легко и естественно сохраняются размеры и положения окон в примерах проектов к библиотеке, при этом вью-модели кросс-платформенны и полностью чисты от интерфейсной логики.
Обратите внимание на следующие конструкции
4) Встроенные и Композитные Конвертеры (Inline & Composite Converters)
Порой встречается необходимость доступа из конвертера к представлению или его контексту данных. Для этих целей можно применить паттерн IInlineConverter
Суть метода в том, что вместо создания нового класса для конвертера мы просто перемещаем методы Convert и ConvertBack в Code Behind представления в качестве обработчиков события Converting и ConvertingBack. Это даёт полный доступ к представлению, где применяется данный экземпляр конвертера. Пример использования легко отыскать в исходных кодах.
Паттерн ICompositeConverter позволяет соединять конвертеры в цепочки, что помогает иногда избежать создания новых классов-конвертеров. Как его применять, следует посмотреть в исходных кодах.
5) Стеллажи для Grid (Rack for Grid)
Здесь достаточно взглянуть на код, чтобы всё стало понятно.
Пожалуй, для данной статьи достаточно, она носит ознакомительный обзорный характер. Мы рассмотрели далеко не все возможности библиотеки, за кадром остались локализация, валидация данных, расширения привязки, другие типы конвертеров, синтаксический сахар и много других мелочей. При наличии интереса к материалам будут и другие статьи, поэтому не оставайтесь равнодушны, вливайтесь в обсуждения, выражайте свои отзывы в комментариях или по е-мэил, делитесь с другими.
P.S. По ссылке немного устаревшие, но всё ещё актуальные материалы
С версии 2.0 она стала платной для коммерческого использования, но остаётся свободной для учебных целей и проектов с открытым исходным кодом. Стоимость лицензии составляет 30$ на одного разработчика.
Вложив небольшую сумму денег и день-два в углубленное изучение её особенностей, вы сохраните недели и месяцы труда на реальных проектах. Более того, даже если вы опытный разработчик, значительно повысите свой технический уровень, архитектурные навыки и системность мышления. В данный момент всё зависит лишь от вашей усидчивости и трудолюбия. Гарантирую, что оно того стоит.

Первым делом нужно загрузить библиотеку с официального сайта или альтернативных источников:
сайт,
dropbox,
onedrive,
google.drive, — после чего распаковать архив и открыть тестовые проекты HelloAero, BankOnline, Sparrow, — они помогут быстрее войти в курс дела и послужат живыми примерами.
Следует отметить, что библиотека достаточно легко внедряется в уже существующие решения, поэтому буквально сразу может быть использована в деле. Итак, рассмотрим что же в ней примечательного на первый взгляд.
1) Эвокаторы Свойств и Команд (Property and Command Evocators)
Чтобы подписаться на событие уведомления об изменении значения свойства вместо классической конструкции
PropertyChanged += (o, args) =>
{
if (args.PropertyName == "Text") { ... };
}
достаточно использовать более лаконичный вариант на основе лямбда выражений
this[() => Text].PropertyChanged += (o, args) => { ... };
Парсинг выражения выполняется лишь единожды при инициализации, поэтому на производительность это не оказывает существенного влияния, но делает код намного более линейным и читаемым.
Обработчики для маршрутизируемых и контекстных команд задаются схожим образом.
this[MediaCommands.Play].CanExecute += (o, args) => args.CanExecute = /* conditions */;
this[MediaCommands.Play].Executed += (o, args) => { ... };
this[Context.Make].CanExecute += (o, args) => args.CanExecute = /* conditions */;
this[Context.Make].Executed += (o, args) => { ... };
Контекстные команды — кросс-платформенная и безопасная от утечек памяти реализация команд, отдалённо напоминающая логику работы маршрутизируемых команд в WPF.
2) Равноправные Инжекции путём Экспанирования (Equitable Injections via Exposable Way)
Классические инжекции зависимостей в конструктор вью-моделей не самая лучшая практика. Да, существует множество контейнеров, реализующих такую функциональность и распространён такой подход повсеместно, но он обладает целым рядом недостатков и накладывает большие ограничения на проектируемую систему. Об этом можно долго говорить, поэтому сейчас обозначим лишь суть проблемы: инжекции в конструктор создают иерархические зависимости, то есть при возникновении необходимости добраться из низкоуровневой вью-модели к высокоуровневой без сомнительных решений нельзя. Однако существует способ прямых инжекции вью-моделей без создания иерархических зависимостей, сохраняющий их равноправность! Это очень важное свойство для сериализации и десереализации замкнутых графов объектов, что оставляет возможность для полного сохранения и восстановления логического и визуалного состояний всего приложения при его перезагрузке.
Реализуется подобное очень просто и естественно. Посмотрите пример кода в проекте HelloAero в разделе Exposable.
Пример кода
[DataContract]
public class GuyViewModel : ContextObject, IExposable
{
[DataMember]
public int Kisses
{
get { return Get(() => Kisses); }
set { Set(() => Kisses, value); }
}
public void Expose()
{
var girlViewModel = Store.Get<GirlViewModel>();
this[() => Kisses].PropertyChanged += (sender, args) =>
{
Context.Get("KissGirl").RaiseCanExecuteChanged();
Context.Get("KissGuy").RaiseCanExecuteChanged();
};
this[Context.Get("KissGirl")].CanExecute += (sender, args) =>
args.CanExecute = Kisses > girlViewModel.Kisses - 2;
this[Context.Get("KissGirl")].Executed += (sender, args) =>
girlViewModel.Kisses++;
}
}
[DataContract]
public class GirlViewModel : ContextObject, IExposable
{
[DataMember]
public int Kisses
{
get { return Get(() => Kisses); }
set { Set(() => Kisses, value); }
}
public void Expose()
{
var guyViewModel = Store.Get<GuyViewModel>();
this[() => Kisses].PropertyChanged += (sender, args) =>
{
Context.Get("KissGirl").RaiseCanExecuteChanged();
Context.Get("KissGuy").RaiseCanExecuteChanged();
};
this[Context.Get("KissGuy")].CanExecute += (sender, args) =>
args.CanExecute = Kisses > guyViewModel.Kisses - 3;
this[Context.Get("KissGuy")].Executed += (sender, args) =>
guyViewModel.Kisses++;
}
}
3) Умное Состояние и Умные Свойства (Smart State & Smart Properties)
В языке JavaScript реализована очень мощная концепция слаботипизированных свойств, а также встроенные возможности простой сериализации и десериализации объектов, что делает его незаменимым при разработке сложных динамических интерфейсов. Отчасти эти концепции нашли отражение в механизмах Smart State и Smart Properties.
Взгляните, насколько легко и естественно сохраняются размеры и положения окон в примерах проектов к библиотеке, при этом вью-модели кросс-платформенны и полностью чисты от интерфейсной логики.
Обратите внимание на следующие конструкции
WindowStyle="{Smart 'WindowStyle, SingleBorderWindow'}"
ResizeMode="{Smart 'ResizeMode, CanResizeWithGrip'}"
Height="{Smart 'Height, 600'}"
Width="{Smart 'Width, 800'}"
4) Встроенные и Композитные Конвертеры (Inline & Composite Converters)
Порой встречается необходимость доступа из конвертера к представлению или его контексту данных. Для этих целей можно применить паттерн IInlineConverter
public class ConverterEventArgs : EventArgs
{
public object ConvertedValue { get; set; }
public object Value { get; private set; }
public Type TargetType { get; private set; }
public object Parameter { get; private set; }
public CultureInfo Culture { get; private set; }
public ConverterEventArgs(object value, Type targetType, object parameter, CultureInfo culture)
{
TargetType = targetType;
Parameter = parameter;
Culture = culture;
Value = value;
}
}
public interface IInlineConverter : IValueConverter
{
event EventHandler<ConverterEventArgs> Converting;
event EventHandler<ConverterEventArgs> ConvertingBack;
}
Суть метода в том, что вместо создания нового класса для конвертера мы просто перемещаем методы Convert и ConvertBack в Code Behind представления в качестве обработчиков события Converting и ConvertingBack. Это даёт полный доступ к представлению, где применяется данный экземпляр конвертера. Пример использования легко отыскать в исходных кодах.
Паттерн ICompositeConverter позволяет соединять конвертеры в цепочки, что помогает иногда избежать создания новых классов-конвертеров. Как его применять, следует посмотреть в исходных кодах.
public interface ICompositeConverter : IValueConverter
{
IValueConverter PostConverter { get; set; }
object PostConverterParameter { get; set; }
}
5) Стеллажи для Grid (Rack for Grid)
Здесь достаточно взглянуть на код, чтобы всё стало понятно.
<Grid Rack.Rows="* 20\Auto * 2* */100 * *" Rack.Columns="* 50\*/100 *">
<!--...-->
</Grid>
equals
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition MinHeight="20" Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="2*"/>
<RowDefinition Height="*" MaxHeight="100"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition MinWidth="100" Width="*" MaxWidth="300"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!--...-->
</Grid>
Пожалуй, для данной статьи достаточно, она носит ознакомительный обзорный характер. Мы рассмотрели далеко не все возможности библиотеки, за кадром остались локализация, валидация данных, расширения привязки, другие типы конвертеров, синтаксический сахар и много других мелочей. При наличии интереса к материалам будут и другие статьи, поэтому не оставайтесь равнодушны, вливайтесь в обсуждения, выражайте свои отзывы в комментариях или по е-мэил, делитесь с другими.
P.S. По ссылке немного устаревшие, но всё ещё актуальные материалы
Only registered users can participate in poll. Log in, please.
Вызвала ли у вас интерес библиотека?
43.1% да, пишите о ней ещё50
18.1% просмотрел примеры, но нет, не моё21
38.79% не вызвала интреса, даже примеры не посмотрел45
116 users voted. 51 users abstained.