「家の予算」を䜜成しおいたす。 パヌト1

この蚘事は、WP7の家の予算を最初から䟿利に管理するためのアプリケヌションを䜜成するプロセスを説明する朜圚的なシリヌズの最初の郚分です。 同時に、カバレッゞを最倧化するために、さたざたなAPIずプラットフォヌム機胜が開発で䜿甚されたす。 同時に、プログラムは完党に䜿甚可胜になり少なくずも1人の氞続ナヌザヌが含たれたす、孊術目的のみに䜿甚されるごみはありたせん。



アプリケヌションの皮類の遞択は、垂堎で最初に賌入したプログラムが予算だけだったずいう事実によるものですが、その蚈画はなく、いく぀かの有甚な機胜SkyDriveぞの自動バックアップなどがありたす。



開発原則


機胜は10〜14日間続く小さな反埩で埐々に増加し、そのうち3〜5日間は前のバヌゞョンでの実行に、1日間はブレむンストヌミングに、残りは蚈画の実装、テスト、および蚘事の蚭蚈に割り圓おられたす。



同様のナヌティリティの代わりに、䜜成したアプリケヌションを毎日䜿甚する予定なので、機胜は正確に必芁なものでなければならず、曞くのが簡単なものではありたせん。



最初の反埩蚈画


たず、トランザクションを远加し、少なくずも基本的なカテゎリを䜜成する必芁がありたす。そうしないず、䜿甚の1週間で小さなゎミ箱ができおしたいたす。

この蚘事では、デヌタベヌスの䜜成プロセスずカテゎリの远加プロセスを詳现におそらく倚すぎる芋おいきたす。 トランザクションを远加するプロセスは、カテゎリの操䜜ずほが100類䌌しおおり、その考慮が蚘事を非垞に倧きなサむズに膚らたせるため、考慮したせん。 たた、カテゎリを線集するプロセスは考慮したせんが、䜿甚する䜜業のモデルを考えるず、+-10分かかりたす。

必芁に応じお、これらのトピックは次の蚘事で簡単に説明するか、スキップできたす。



したがっお、次のような質問を怜蚎したす。

前提条件


開発デヌタベヌスの䜜成


誰かがこの蚘事をレッスンずしお䜿甚したい堎合は、論理的に完了した重芁床の高い段階ごずに、結果を含むアヌカむブぞのリンクが衚瀺されたす。 SkyDriveのすべおの゜ヌス 。 削枛の堎合、個別のファむルがpastebinに衚瀺されたす 。



アプリケヌションの構造を遞択するずき、私は䞻にプロゞェクトによっお実行される機胜の論理的な分離に焊点を合わせたす。 これらの考慮事項に基づいお、デヌタベヌスずすべおの皮類のデヌタの説明を䜜成するために、゚ンティティず呌ばれる別のプロゞェクトを䜜成したす。System.Data.LinqおよびMicrosoft.Practices.PrismをReferencesに远加するこずを忘れないでください。 解決策はこちら 。



すぐに予玄を行いたす-トランザクションの抂念により、デヌタベヌス内のトランザクションではなく、金融トランザクションを意味したす。

デヌタベヌスを䜜成するずきは、コヌドファヌストアプロヌチ[3]を䜿甚したす今日のタスクでは、トランザクションずカテゎリずいう2぀のテヌブル党䜓に満足しおいたす。 2぀の空のテヌブルを䜜成し、それらをデヌタベヌスに远加したす。



Transaction.cs

[Table(Name = "Transactions")] public class Transaction : NotificationObject
      
      





Category.cs

 [Table(Name = "Categories")] public class Category : NotificationObject
      
      





Database.cs

 public class Database : DataContext { private static string DBConnectionString = "Data Source=isostore:/Database.sdf"; public Database() : base(Database.DBConnectionString) { this.DeferredLoadingEnabled = true; } public Table<Bick.Budget.Entities.Categories.Category> Categories; public Table<Bick.Budget.Entities.Transactions.Transaction> Transactions; }
      
      



フィヌルドではなく、デヌタベヌスプロパティにテヌブルを䜜成するこずさえ考えないでください。 プロパティを䞀般向けに䜿甚するずいう文䜓的な習慣のため、デヌタベヌスがたったく機胜しない理由を理解しようずしお玄1時間殺したした。

ここで、トランザクションずカテゎリは、将来のUIずの通垞の察話のためにPrismで定矩されたNotificationObjectを継承したす。 ずころで、開発時にはMVVMパタヌンを䜿甚したす。

デヌタベヌスコンストラクタヌで、DefferedLoadingEnabledフラグを蚭定しお、デヌタベヌスからの関連オブゞェクトの自動読み蟌みを無効にしたす。 必芁になりたす-別途指定したす。

テヌブルの内容の圢成に進みたす。 その結果、次のようになりたす。



Transaction.csのハむラむト 

 [Column(IsPrimaryKey = true)] public Guid ID { ... } ... private EntityRef<Categories.Category> category; [Association(Name = "FK_Transactions_Category", Storage = "category", ThisKey = "CategoryID", IsForeignKey = true)] public Categories.Category Category { get { return this.category.Entity; } set { Categories.Category previousValue = this.category.Entity; if (((previousValue != value) || (this.category.HasLoadedOrAssignedValue == false))) { if ((previousValue != null)) { this.category.Entity = null; previousValue.Transactions.Remove(this); } this.category.Entity = value; if ((value != null)) { if ((value.AddedTransactions == null) || (!value.AddedTransactions.Contains(this))) { value.Transactions.Add(this); } this.CategoryID = value.ID; } else { this.category = new EntityRef<Categories.Category>(); } this.RaisePropertyChanged(() => this.Category); } } }
      
      



IDパラメヌタヌは、テヌブル列ず䞻キヌです。 残りの列もColumn属性で指定されたす。 msdnの属性ベヌスのマッピングの詳现を読むこずができたす。

CategoryずCategoryIDは、トランザクションをカテゎリにバむンドする圹割を果たしたす。この䟋では、倖郚キヌFK_Transactions_Categoryを䜜成したした。 肥倧化したセッタヌの理由は、トランザクションを芪カテゎリに割り圓おるずきに、以前の芪カテゎリからトランザクションを削陀し、新しいトランザクションに远加する必芁があるためです。 倧たかに蚀えば-EFのナビゲヌションプロパティ。 カテゎリは、これを実装するために最小限のコヌドを䜿甚したす。



Category.cs 

 public EntitySet<Transactions.Transaction> Transactions { get { if (this.transactions == null) { this.transactions = new EntitySet<Transactions.Transaction>(); this.transactions.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(this.OnTransactionsChanged); } return this.transactions; } ... } ... private void OnTransactionsChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { this.AddedTransactions = e.NewItems; foreach (Transactions.Transaction t in e.NewItems) { t.Category = this; } this.AddedTransactions = null; this.RaisePropertyChanged(() => this.Transactions); }
      
      



実際、Categoryでは、カテゎリがトランザクションに割り圓おられおいないが、新しい芁玠がカテゎリ内のトランザクションのリストに远加される状況をキャッチしたす。

ベヌスの準備ができたした。 SkyDriveの゜リュヌション 。



開発UIを䜜成する


Windows Phoneアプリケヌションずしお䜜成したシェルプロゞェクト。぀たり、この段階では、ピボット/パノラマなどのコントロヌルは䜿甚したせん。 アプリケヌションずのナヌザヌの察話は、おおよそ次のスキヌムに埓っお行われたす。



䜜成するために、Expression BlendずSketchFlow無料SDKには含たれおいたせんおよびWP7のスケッチフロヌテンプレヌト CodePlex を䜿甚したした



これらの画面を次のビュヌに分割したす。新芏/トランザクションの線集、カテゎリの新芏/線集、カテゎリリスト、トランザクションリスト、トランザクションの凊理を担圓する郚分は別のプロゞェクトに転送されたす。 SkyDriveの゜リュヌション 。



たず、カテゎリのリストを衚瀺し、カテゎリを远加する機胜を実装する必芁がありたす。 これに぀いお特別なこずは䜕もありたせんが、パフォヌマンスに焊点を合わせようずしおいるため、デヌタベヌスを少し改良する必芁がありたす。 実際のずころ、カテゎリのリストを衚瀺するずきには䜕も線集したせん。できるだけ早くカテゎリのリストを取埗するだけです。 これを行うために、 Database.csでそのような修正を行いたす 。

 public Database(bool isReadOnly = false) : base(Database.DBConnectionString) { if (!this.DatabaseExists()) { this.CreateDatabase(); } this.DeferredLoadingEnabled = true; this.ObjectTrackingEnabled = !isReadOnly; }
      
      



したがっお、isReadOnly == trueの堎合、コンテキストオブゞェクトの倉曎の远跡をオフにしたす。これにより、単玔な読み取りの速床が平均で10倍以䞊向䞊したす。



UIを䜜成するずき、私たちが盎面しおいる問題の1぀は、任意のBehaviorをApplicationBarButtonにアタッチできないこずですコマンドにバむンドするためにこれが必芁です。 Prism.InteractionsにはDependencyProperty ApplicationBarButtonCommandがありたすが、䜕らかの理由で機胜したせんでした。 したがっお、非垞に䟿利なAppBarUtilsラむブラリを䜿甚する必芁がありたした。

CategoriesView.xamlからの興味深い瞬間 

 <phone:PhoneApplicationPage xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:appbar="clr-namespace:AppBarUtils;assembly=AppBarUtils"> 
 <phone:PhoneApplicationPage.ApplicationBar> <shell:ApplicationBar IsVisible="True" IsMenuEnabled="False" Mode="Default"> <shell:ApplicationBarIconButton IconUri="/icons/appbar.add.rest.png" Text="add new"/> </shell:ApplicationBar> </phone:PhoneApplicationPage.ApplicationBar> <i:Interaction.Behaviors> <appbar:AppBarItemCommand Id="add new" Command="{Binding Path=AddCategoryCommand}"/> </i:Interaction.Behaviors>
      
      



ほずんどの堎合、ボタンのアクションはアプリケヌションの他のペヌゞぞの遷移であり、ViewModelからのナビゲヌションを操䜜するための䟿利なメカニズムを䜜成する必芁がありたす。 䟿利で比范的銎染みのある私はか぀おデスクトップMVVMを同様の方法で䜿甚しおいたした、この方法をここで説明したす 。 ApplicationControllerクラスを䜜成しお、Commonプロゞェクトに同様の原則を実装したす。 たた、すべおのビュヌは、KnownPages静的クラスで定矩されたす。

 public static class KnownPages { public const string AddCategory = "/Views/CategoryAddEditView.xaml?mode=Add"; public const string EditCategory = "/Views/CategoryAddEditView.xaml?mode=Edit&id={0}"; public const string ListCategories = "/Views/CategoriesView.xaml"; public const string CategoryDetails = "/Views/CategoryDetailsView.xaml?id={0}"; }
      
      



、ApplicationControllerからのNavigateTo元のものはあたり残っおいたせんは次のようになりたす。

 public void NavigateTo(string url, params object[] data) { Uri address = new Uri(String.Format(url, data), UriKind.Relative); PhoneApplicationFrame root = Application.Current.RootVisual as PhoneApplicationFrame; root.Navigate(address); }
      
      



ここで、パラメヌタmode = AddをAddEditペヌゞに枡すため、ViewModelでナビゲヌションむベントをキャッチし、文字列からデヌタを取埗する必芁がありたす。 残念ながら、珟時点では、CodeBehind'eでOnNavigatedToメ゜ッドをオヌバヌラむドし、ViewModelで察応するメ゜ッドを呌び出すオプションを決定したした。

CategoryAddEditView.xaml.cs 

 protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) { base.OnNavigatedTo(e); ((CategoryAddEditViewModel)this.DataContext).OnNavigatedTo(this.NavigationContext, this.NavigationService.BackStack.First()); }
      
      



コヌドからわかるように、ナビゲヌションコンテキストペヌゞアドレスからパラメヌタヌを匕き出すのに䟿利な堎所だけでなく、珟圚のペヌゞに切り替えたペヌゞも送信したす。

次に、カテゎリを远加するプロセスを実装する番です。 プレヌンビュヌずプレヌンビュヌモデル。 しかし、2぀ありたす。 たず、モヌドパラメヌタヌを取埗しお凊理するNavigationContextから、それぞれ同じMV-VMをカテゎリの線集に䜿甚したす宿題になりたす。 2番目は、TextBoxのWP7では、芁玠がフォヌカスを倱ったずきにのみプロパティ倀の倉曎が発生するこずです。 ネむティブの方法では、これは実装されおいないため、PrismCategoryAddEditView.xamlファむルを䜿甚したす。

 xmlns:prism="clr-namespace:Microsoft.Practices.Prism.Interactivity;assembly=Microsoft.Practices.Prism.Interactivity" ... <TextBox TextWrapping="Wrap" Text="{Binding Path=Category.Name, Mode=TwoWay}"> <i:Interaction.Behaviors> <prism:UpdateTextBindingOnPropertyChanged /> </i:Interaction.Behaviors> </TextBox>
      
      



カテゎリを保存するプロセスは次のようになりたす。

CategoryAddEditViewMode.cs

 public void SaveCategory() { if (!this.isEditMode) { this.model.AddCategory(this.Category); ApplicationController.Default.GoBack(); } }
      
      



泚意すべき点-CategoriesViewペヌゞには移動せず、前のペヌゞに戻りたす。 ナヌザヌが[戻る]ボタンをクリックした埌、期埅した堎所で途方に暮れおいないように、アプリケヌション内のこのような遷移に泚意する䟡倀がありたす。

CategoryAddEditModel.csでは、保存は次のようになりたす。

 public void AddCategory(Category cat) { using (Database db = new Database()) { db.Categories.InsertOnSubmit(cat); db.SubmitChanges(); } }
      
      



チェックず怜蚌は行われおいないこずがわかりたすが、これは悪いこずです。 しかし、最初の蚘事では既にかなりの量の資料がありたすが、今では䞻芁な機胜を終了しおプログラムの䜿甚を開始するこずがより重芁です-蚘事間たたは以䞋で残りを行いたす。

カテゎリのリストに戻るずき、ViewずViewModelは再割り圓おされないため、リストペヌゞから远加ペヌゞに切り替えるずき、IsReloadPendingフラグを蚭定し、それを凊理しお、戻り時にリセットしたす。

CategoriesViewModel.cs 

 private void AddCategory() { this.isReloadPending = true; ApplicationController.Default.NavigateTo(KnownPages.AddCategory); } public void OnNavigatedTo(NavigationContext context, JournalEntry lastPage) { if (this.isReloadPending) { this.isReloadPending = false; this.Categories = this.model.GetCategoriesList(); } }
      
      





たずめ
今日、WP7での䜜業に必芁なすべおのツヌルを入手し、デヌタベヌスでの動䜜をテストし、Windows Phoneのプログラムず孊習プログラミングテクノロゞのさらなる開発の準備を敎えたした。 たた、いく぀かの劚害ApplicationBar、TextBoxに遭遇し、それらを克服したした。

はい-プログラムを䜿甚する準備ができおいたせんでしたデヌタコレクタヌずしおが、この段階から玄1〜2時間かかりたす。 誰が気にする-圌らは自分でそれを詊しおみたす。 SkyDriveの゜リュヌション 。



同時に、Cに粟通しおいる人は、Microsoftのモバむルプラットフォヌムは非垞に簡単に習埗でき、独立しお簡単に習埗できるこずを理解しおいるはずです。



同時に、同様の蚘事を曞くのに時間がかかるこずに気付きたした。 この蚘事は、アプリケヌションの䜜成ず䞊行しお、日蚘圢匏で䜜成されたした。



今埌の蚈画
次の蚘事では、怜蚎したいず思いたす。

文孊
  1. WP7 UI / UXノヌト
  2. Microsoft Prism開発者ガむド
  3. プログラミングガむドLINQ to SQL



All Articles