Developers Club geek daily blog

2 years, 9 months ago
Aero Framework — the advanced library for industrial and individual development of the cross-platform XAML oriented applications using concepts of MVVM design. Its main advantages — intuitive clarity, limit laconicism, minimalistichnost and high high-speed performance.

From version 2.0 it became paid for commercial use, but remains free for the educational purposes and projects open source. The cost of the license makes $30 for one developer.

Having enclosed the small sum of money and day - two in profound studying of its features, you save weeks and months of work on real projects. Moreover, even if you the experienced developer, considerably will raise the technological level, architectural skills and systemacity of thinking. At present everything depends only on your assiduity and diligence. I guarantee that it is worth it.

image

First of all it is necessary to load library from the official site or alternative sources:
site,
dropbox,
onedrive,
google.drive — then to unpack archive and to open test projects of HelloAero, BankOnline, Sparrow — they will help to be up on quicker and will serve as living examples.

It should be noted that the library rather easily is implemented into already existing solutions therefore just at once it can be used in business. So, we will consider that in it remarkable at first sight.

1) Evokatora Svoystv and Teams (Property and Command Evocators)

To subscribe for event of the notification on change of value of property instead of classical construction

PropertyChanged += (o, args) =>
{
	if (args.PropertyName == "Text") { ... };
}

it is enough to use more laconic option on basis lambda of expressions

this[() => Text].PropertyChanged += (o, args) => { ... };

Parsing of expression is executed only once at initialization therefore it has no essential impact on productivity, but does code much more linear and readable.

Processors for the routed and context teams are set similarly.

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) => { ... };

Context teams — the implementation of teams, cross-platform and safe from memory leaks which is bearing a faint resemblance to logic of work of the routed teams in WPF.

2) Equal Injections by Ekspanirovaniya (Equitable Injections via Exposable Way)

I twist classical injections of dependences in the designer - models not the best practice. Yes, there is set of the containers implementing such functionality and such approach everywhere is widespread, but it possesses a number of shortcomings and imposes big restrictions on projectible system. It is possible to speak about it long therefore now we will designate only problem essence: injections in the designer create hierarchical dependences, that is at emergence of need to reach from the low-level I twist - to high-level without doubtful solutions it is impossible for model. However there is way of straight lines of injection twist - models without creation of hierarchical dependences, saving their ravnopravnost! This very important property for serialization and deserialising of the closed object graphs that leaves opportunity for full save and recovery of logical and visual statuses of all application at its reset.

It is implemented similar very simply and naturally. Look at code sample in the HelloAero project in the section Exposable.

Code sample
    [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 Status and Smart Properties (Smart State &Smart Properties)

In the JavaScript language very powerful concept of slabotipizirovanny properties, and also the built-in opportunities of simple serialization and deserialising of objects that does it irreplaceable when developing difficult dynamic interfaces is implemented. Partly these concepts have found reflection in Smart State and Smart Properties mechanisms.

Look, how easily and naturally the sizes remain and provisions of windows in examples of projects to library, thus I twist - models cross-platformenny and are completely pure from the interface logic.

Pay attention to the following constructions

    WindowStyle="{Smart 'WindowStyle, SingleBorderWindow'}"
    ResizeMode="{Smart 'ResizeMode, CanResizeWithGrip'}"
    Height="{Smart 'Height, 600'}" 
    Width="{Smart 'Width, 800'}"


4) Built-in and Composite Converters (Inline &Composite Converters)

Occasionally need of access from the converter to representation or its context of data meets. It is possible to apply IInlineConverter pattern to these purposes

    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;
    }

Method essence that instead of creation of new class for the converter we simply move the Convert and ConvertBack methods to representation Code Behind as processors of event of Converting and ConvertingBack. It gives full access to representation where this copy of the converter is applied. It is easy to find example of use in source codes.

The pattern of ICompositeConverter allows to connect converters in chains that helps to avoid creation of new classes converters sometimes. As to apply it, it is necessary to look in source codes.

    public interface ICompositeConverter : IValueConverter
    {
        IValueConverter PostConverter { get; set; }
        object PostConverterParameter { get; set; }
    }


5) Racks for Grid (Rack for Grid)

Here it is enough to look at code that everything became clear.

<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>


Perhaps, for this article it is enough, it has fact-finding survey character. We have considered not all opportunities of library, localization, validation of data, expansions of binding, other types of converters, syntax sugar have stayed behind scenes and it is a lot of other trifles. With interest in materials will be also other articles therefore do not remain are indifferent, join discussions, express the responses in comments or on e-meil, share with others.

P.S. According to the link a little outdated, but still actual materials
Whether the library has caused in you interest?

102 persons have voted. 44 persons have refrained.

Only the registered users can participate in poll. Enter, please.


This article is a translation of the original post at habrahabr.ru/post/268151/
If you have any questions regarding the material covered in the article above, please, contact the original author of the post.
If you have any complaints about this article or you want this article to be deleted, please, drop an email here: sysmagazine.com@gmail.com.

We believe that the knowledge, which is available at the most popular Russian IT blog habrahabr.ru, should be accessed by everyone, even though it is poorly translated.
Shared knowledge makes the world better.
Best wishes.

comments powered by Disqus