Aeroフレームワークは、WPFの新しい息吹です。 MVVMを上回っています

Aeroフレームワークは、 MVVM設計の概念を使用した、クロスプラットフォームXAML指向アプリケーションの産業および個人開発向けの高度なライブラリです。 その主な利点は、直感的な明快さ、極端な簡潔さ、ミニマリズム、高速性です。



バージョン2.0以降、商用利用に対しては有料になりましたが、教育目的やオープンソースプロジェクトには無料のままです。 ライセンスの費用は、開発者ごとに30ドルです。



その機能の詳細な調査に少額のお金と1〜2日を投資することで、実際のプロジェクトでの作業を数週間から数か月節約できます。 さらに、経験豊富な開発者であっても、技術レベル、アーキテクチャスキル、体系的な思考を大幅に向上させます。 現時点では、それはすべてあなたの忍耐力と勤勉さにかかっています。 私はそれが価値があることを保証します。



画像



まず、公式ウェブサイトまたは代替ソースからライブラリをダウンロードする必要があります。

サイト

ドロップボックス

onedrive

google.drive-アーカイブを解凍し、 HelloAeroBankOnlineSparrowテストプロジェクトを開きます-これらは、物事をより迅速に邪魔するのを助け、実例として役立ちます。



ライブラリは既存のソリューションに非常に簡単に実装できるため、ビジネスで文字通りすぐに使用できることに注意してください。 それでは、一目で何が注目に値するかを考えてみましょう。



1)プロパティおよびコマンドエボカトール



従来の構成ではなく、プロパティ変更通知イベントをサブスクライブするには



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





ラムダ式に基づいたより簡潔なバージョンを使用するだけです



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





式の解析は初期化中に1回だけ実行されるため、パフォーマンスに大きな影響はありませんが、コードははるかに線形で読みやすくなります。



ルーティングおよびコンテキストコマンドのハンドラーも同様の方法で設定されます。



 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)Exposable Wayを介した公平な注入



ビューデザイナーへの古典的な依存性注入は、ベストプラクティスではありません。 はい、この機能を実装するコンテナは多数あり、このアプローチはどこにでも普及していますが、多くの欠点があり、設計されたシステムに大きな制限を課しています。 これについて長い間話すことができるので、問題の本質を概説するだけです:コンストラクターへの注入は、階層的な依存関係を作成します。つまり、低レベルのビューモデルから疑わしい決定なしに高レベルのビューモデルに移行する必要が生じたときです。 ただし、階層の依存関係を作成せずにビューモデルを直接挿入し、それらの同等性を維持する方法があります。 これは、オブジェクトの閉じたグラフのシリアル化と非シリアル化のための非常に重要なプロパティであり、再起動時にアプリケーション全体の論理的および視覚的状態を完全に保存および復元できます。



これは非常に簡単かつ自然に実装されます。 ExposableセクションのHelloAeroプロジェクトのサンプルコードをご覧ください。



コード例
  [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)スマートステートとスマートプロパティ



JavaScriptは、弱く型付けされたプロパティという非常に強力な概念を実装し、オブジェクトの単純なシリアル化と逆シリアル化のための組み込み機能を備えているため、複雑な動的インターフェイスの開発に不可欠です。 部分的に、これらの概念は、 スマート状態スマートプロパティのメカニズムに反映されます



ライブラリのプロジェクトの例で、ウィンドウのサイズと位置がどれだけ簡単かつ自然に保持されているか、ビューモデルはクロスプラットフォームであり、インターフェイスロジックが完全に揃っていることを確認してください。



次の設計に注意してください



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







4)インラインおよび複合コンバーター



コンバータからビューまたはそのデータコンテキストにアクセスする必要がある場合があります。 これらの目的のために、 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; }
      
      





このメソッドの本質は、コンバーターの新しいクラスを作成する代わりに、 ConvertingおよびConvertBackBackイベントのハンドラーとしてConvert メソッドConvertBackメソッド分離 コードビューに移動するだけです。 これにより、コンバーターのこのインスタンスが使用されているビューに完全にアクセスできます。 使用例は、ソースコードで簡単に見つけることができます。



ICompositeConverterパターンを使用すると、コンバーターをチェーンに接続できます。これにより、新しいコンバータークラスの作成を回避できる場合があります。 使用方法については、ソースコードをご覧ください。



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







5) グリッド用ラック( グリッド用ラック)



ここで、コードを見て、それを明確にします。



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







この記事ではおそらく、ガイダンスのみを目的としています。 ライブラリのすべての機能、ローカライズ、データ検証、バインディング拡張、他のタイプのコンバーター、構文シュガー、その他多くのささいなことは舞台裏に残っていました。 素材に興味がある場合は、他の記事がありますので、無関心ではなく、ディスカッションに参加し、コメントまたは電子メールでフィードバックを表明し、他の人と共有してください。



PS リンクは少し時代遅れですが、それでも関連資料です



All Articles