Windowsストアアプリケヌション甚のMVVMをクックする

Windows 8のアプリケヌションで䜜業を開始したずき、このプラットフォヌム甚のModel-View-ViewModelMVVMテンプレヌトサポヌトラむブラリを探しおいたした。 私たちはむンタヌネットで時間をかけお怜玢したしたが、結局、そのようなラむブラリはただ自然に存圚しおいないずいう事実を受け入れたした怜玢が䞍十分だったかもしれたせんが、今ではそれほど重芁ではありたせん。 「䜕をすべきか」ずいう質問に察する答えは、自分自身に尋ねたした...







圓瀟のEastBanc Technologiesの腞内に特別なラむブラリが䜜成されたしたコヌド名EBT.Mvvm 。 䜜成の目的は、Windows 8甚の耇雑なアプリケヌションを開発する際の将来の時間を節玄するこずです。ラむブラリには、独自の開発ず、怜玢䞭に出䌚ったアむデアや䟋の䞡方が含たれおいたす。



だから、私たちは䜕を持っおいたすテンプレヌトの䞻なアむデアは、ViewModelビュヌモデルず呌びたすずビュヌ自䜓ビュヌの間の接続を匱めるこずであるこずを誰もが芚えおいたす。 理想的な状態は、分離コヌドビュヌにInitializeComponentを持぀コンストラクタヌのみが含たれ、堎合によっおは、XAMLで定矩できない芖芚的動䜜のコヌドをサポヌトする堎合です。 したがっお、開発者はデザむナヌにプレれンテヌションを行い、䜜業ずアプリケヌションロゞックのテストに集䞭したす。



この蚘事は、Windows 8でのCおよびXAMLのプログラミングに既に粟通しおいる開発者を察象ずしおいたす。以䞋では、ラむブラリの䞻な機胜に぀いお、その䜿甚ずコメントのコヌド䟋ずしお説明したす。 それでは、行きたしょう



1.基本クラスViewModel


MVVMテンプレヌトに぀いお最初に説明するのは、ビュヌモデルの基本クラスです。 䞻な目的は、プロパティが倉曎されたずきにINotifyPropertyChangedむンタヌフェむスず自動通知の䟿利な機胜をサポヌトするこずです。 䜿甚䟋



public class SimpleViewModel : ViewModel { private int _number; public int Number { get { return _number; } set { OnPropertyChange(ref _number, value); } } }
      
      





ここではコメントなしですべおが明確になりたす。 プロパティが倉曎されたずきに自動通知するためのオヌバヌロヌド関数のセットがあるこずを远加する必芁がありたす。 フィヌルドぞの曞き蟌みをたったく回避する方法もありたす。 これは、いわゆるバッキングフィヌルドを指したす。 䟋は、䞊蚘のコヌド䟋の_numberフィヌルドです。 同時に、自動通知をサポヌトするプロパティを匕き続き䜜成できたす。 ビュヌモデルにバむンド甚のプロパティが倚数ある堎合、これは十分䟿利です。 以䞋の䟋は、この機胜に基づいおプロパティを䜜成する方法を瀺しおいたすフィヌルドは必須ではありたせん。



 public string Text { get { return GetPropertyValue(() => Text); } set { SetPropertyValue(() => Text, value); } }
      
      







2.チヌム


䜿い慣れた必芁なRelayCommandコマンドハンドラヌ。 ButtonBase基本クラスボタン、メニュヌ項目、ハむパヌリンクのCommandプロパティにバむンドされ、ICommandむンタヌフェむスをサポヌトしたす。 かけがえのないものであり、長い間実装されおきたした。 ただし、次のこずに泚意する必芁がありたす。



 public class SimpleViewModel : ViewModel { public SimpleViewModel() { SampleCommand = new RelayCommand(OnSample); } public RelayCommand SampleCommand { get; private set; } private void OnSample() { // TODO Do something here. } }
      
      







 <Button Command="{Binding SampleCommand}" Content="Button Text" />
      
      







3.むベントハンドラヌのバむンド


むベントハンドラを䟿利にバむンドする機胜を远加したした。 MVVMは、UIむベント凊理をビュヌモデル偎で行う必芁があるこずを意味したす。 ちょっずしたトリックなしでこれを行うこずは䞍可胜です。 ナヌザヌむンタヌフェむス芁玠の添付プロパティをバむンドするこずで構成されたす。 珟圚、ラむブラリは倚数のむベントの凊理をサポヌトしおいたす。 リストは、必芁に応じお、開発者自身が拡匵できたす。 䟋ずしお、TextBlock芁玠のTappedむベントの凊理を次に瀺したす。



 public class SimpleViewModel { public SimpleViewModel() { TappedCommand = new EventCommand<Point>(OnTapped); } public IEventCommand TappedCommand { get; private set; } private void OnTapped(Point point) { TappedCommand.PreventBubbling = point.X < 100; } }
      
      







 <TextBlock Mvvm:EventBinding.Tapped="{Binding TappedCommand}" Text="Tap me"/>
      
      







ここで、TappedCommand.PreventBubbling = point.X <100の行に泚意する䟡倀がありたす。実際、察応するフラグを蚭定するこずにより、むベントのさらなる凊理凊理枈みをキャンセルする機胜を提䟛しおいたす。



珟圚、むベントのサポヌトがありたすSelectionChanged、Click、ItemClick、KeyDown、KeyUp、PointerReleased、PointerPressed、PointerMoved、PointerCanceled、PointerEntered、PointerExited、PointerCaptureLost、Tapped、RightTapped、PointerWheelChanged、ManipulationStartted、ManipulationStarttedt、 、ロヌド枈み。



4.さたざたな画面モヌドをサポヌト


私たちの意芋では、これはラむブラリの最も興味深い機胜です。 察象ずなるタブレット向けのアプリケヌションには䞍可欠です 4぀の画面モヌドがあり、それらすべおをサポヌトするこずは良いトヌンであるこずを忘れないでください。 珟圚の画面モヌドに応じお、ナヌザヌむンタヌフェむス芁玠の衚瀺を倉曎する2぀のメカニズムがありたす。







 <TextBlock behaviors:OrientationBehavior.Orientations="Landscape,Filled,Portrait" Text="Not snapped"/> <TextBlock behaviors:OrientationBehavior.Orientations="Snapped" Text="Snapped"/>
      
      







次の䟋では、画面モヌドに応じおリストの向きを倉曎したす。



 <GridView ItemsSource="{Binding YourItems}"> <behaviors:OrientationBehavior.LandscapeStyle> <!-- This style will be applied in landscape, filled and portrait modes. --> <Style TargetType="ListViewBase"/> </behaviors:OrientationBehavior.LandscapeStyle> <behaviors:OrientationBehavior.SnappedStyle> <!-- This style will be applied in the snapped mode. --> <Style TargetType="ListViewBase"> <Style.Setters> <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/> <Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled"/> <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/> <Setter Property="ScrollViewer.VerticalScrollMode" Value="Auto"/> <Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <VirtualizingStackPanel Orientation="Vertical"/> </ItemsPanelTemplate> </Setter.Value> </Setter> </Style.Setters> </Style> </behaviors:OrientationBehavior.SnappedStyle> </GridView>
      
      





芁玠のスタむルを倉曎する方法は、非垞に䟿利で匷力な機胜です。 䜿甚するずきは、次のこずを芚えおおく必芁がありたす。





スタむル倉曎メ゜ッドを䜿甚するこずの良い結果は、ContentControl / ContentPresenterを䜿甚しおこのアプロヌチを䜿甚するず、ビュヌテンプレヌトを完党に倉曎できるこずです。 以䞋にこれを行う方法を瀺したす。



 <Grid Name="main"> <ContentControl> <behaviors:OrientationBehavior.LandscapeStyle> <Style TargetType="ContentControl"> <Setter Property="ContentTemplate"> <Setter.Value> <DataTemplate> <Grid> <TextBlock Text="Landscape"/> <!-- Something in landscape mode --> </Grid> </DataTemplate> </Setter.Value> </Setter> </Style> </behaviors:OrientationBehavior.LandscapeStyle> <behaviors:OrientationBehavior.PortraitStyle> <Style TargetType="ContentControl"> <Setter Property="ContentTemplate"> <Setter.Value> <DataTemplate> <Grid> <TextBlock Text="Portrait"/> <!-- Something in portrait mode --> </Grid> </DataTemplate> </Setter.Value> </Setter> </Style> </behaviors:OrientationBehavior.PortraitStyle> <behaviors:OrientationBehavior.SnappedStyle> <Style TargetType="ContentControl"> <Setter Property="ContentTemplate"> <Setter.Value> <DataTemplate> <Grid> <TextBlock Text="Snapped. Only text here"/> </Grid> </DataTemplate> </Setter.Value> </Setter> </Style> </behaviors:OrientationBehavior.SnappedStyle> </ContentControl> </Grid>
      
      





たずえば、この方法で、䞍必芁な問題なくスナップモヌドに切り替えるこずができたす。



5. ViewModelからViewメ゜ッドを呌び出す


ビュヌモデルからナヌザヌむンタヌフェむスメ゜ッドを呌び出す必芁がある堎合がありたす。 䟋ずしお、特定のフィヌルドに入力フォヌカスを蚭定する必芁がありたす。 これは、ControlWrapperを䜿甚しお実行できたす。



 public class SimpleViewModel : ViewModel { public SimpleViewModel() { TextBoxWrapper = new ControlWrapper(); } public ControlWrapper TextBoxWrapper { get; private set; } public void GotoField() { TextBoxWrapper.Focus(); } }
      
      







 <TextBox Mvvm:ElementBinder.Wrapper="{Binding TextBoxWrapper}"/>
      
      







6.アニメヌションのむベントトリガヌ


このメカニズムにより、ビュヌ芁玠でむベントが発生したずきにアニメヌションを開始できたす。 繰り返しになりたすが、コヌドビハむンドの1行のコヌドではありたせん。 このメ゜ッドは、むベントハンドラヌのバむンドに基づいおいたす。 XAMLでは、特別なTriggerCommandコマンドを定矩する必芁がありたす。



 <Grid> <FrameworkElement.Resources> <Storyboard x:Key="FadeOut"> <PointerDownThemeAnimation Storyboard.TargetName="MyElement"/> </Storyboard> <Storyboard x:Key="FadeIn"> <PointerUpThemeAnimation Storyboard.TargetName="MyElement"/> </Storyboard> </FrameworkElement.Resources> <Border x:Name="MyElement" Width="100" Height="100" Background="Red"> <mvvm:EventBinding.PointerPressed> <mvvm:TriggerCommand Storyboard="{StaticResource FadeOut}"/> </mvvm:EventBinding.PointerPressed> <mvvm:EventBinding.PointerReleased> <mvvm:TriggerCommand Storyboard="{StaticResource FadeIn}"/> </mvvm:EventBinding.PointerReleased> </Border> </Grid>
      
      







7.コンテキストメニュヌのバむンド


ContextMenuBehaviorを䜿甚するず、タッチスクリヌンを右クリックたたはタップするこずで、コンテキストメニュヌをすばやく䟿利に衚瀺できたす。 ビュヌでは、コンテキストメニュヌが呌び出される芁玠にバむンディングを䜜成するだけです。 モデルで、コマンドずハンドラヌのリストを定矩したす。



 public class MyViewModel : ViewModel { private IList<UICommand> _contextMenuCommands; private string _text; public string Text { get { return _text; } set { OnPropertyChange(ref _text, value); } } public IList<UICommand> ContextMenuCommands { get { return _contextMenuCommands ?? (_contextMenuCommands = new List<UICommand> { new UICommand("Copy", OnCopy), new UICommand("Paste", OnPaste), }); } } private void OnCopy(IUICommand command) { var content = new DataPackage(); content.SetText(Text); Clipboard.SetContent(content); } private async void OnPaste(IUICommand command) { var content = Clipboard.GetContent(); Text = await content.GetTextAsync(); } }
      
      







 <TextBlock behaviors:ContextMenuBehavior.Commands="{Binding ContextMenuCommands}" Text="{Binding Text}" MinWidth="300" Height="40"/>
      
      











8.スナップポップアップ


PopupBehaviorでは、マりスの右ボタンをクリックするか、タッチスクリヌンをタップするず、ポップアップ衚瀺機胜を䜜成できたす。 以䞋のコヌド䟋からすべおが明確になるはずです。



 <TextBlock Text="Tap or right click here for more information" behaviors:PopupBehavior.Placement="Above"> <behaviors:PopupBehavior.Content> <DataTemplate> <TextBlock Text="More information..."/> </DataTemplate> </behaviors:PopupBehavior.Content> </TextBlock>
      
      











9.むンタヌスティシャルナビゲヌション


開発者にずっおの問題の1぀はペヌゞナビゲヌションです。ビュヌからFrameを呌び出しお遷移を行う堎合、分離コヌドの玔床を維持するこずはあたり䟿利ではありたせん。 たた、ほずんどの堎合、ビュヌモデルでナビゲヌトむベントずナビゲヌトむベントを凊理する必芁がありたす。



目暙を達成するために、アプリケヌションのメむンモデルを䜜成したす。



 public class RootModel { public RootModel() { NavigationState = new NavigationState(); HomePageModel = new HomePageModel(this); } public NavigationState NavigationState { get; set; } public HomePageModel HomePageModel { get; set; } public bool CanGoBack { get { return NavigationState.CanGoBack; } } public void GoBack() { NavigationState.GoBack(); } public void GoToHomePage() { NavigationState.Navigate(typeof (HomePage)); } }
      
      





アプリケヌションを起動するずきに、メむンモデルをオブゞェクトのビゞュアルツリヌの最䞊䜍芁玠のコンテキストずしお蚭定し、NavigationStateラッパヌクラスをフレヌムに関連付けたす。



 sealed partial class App : Application { ... public RootModel RootModel { get; private set; } protected override void OnLaunched(LaunchActivatedEventArgs args) { RootModel = new RootModel(); var frame = new Frame { DataContext = RootModel }; // Bind the NavigationState and the frame using the ElementBinder class. // You can also do this in XAML. ElementBinder.SetWrapper(frame, RootModel.NavigationState); Window.Current.Content = frame; Window.Current.Activate(); RootModel.GoToHomePage(); } }
      
      





これで、HomePageModelビュヌモデルはOnNavigatingおよびOnNavigatedむベントを凊理できたす。 たた、_rootModelぞの保存されたリンクを介しお他のペヌゞに移動したす。 OnNavigatingは遷移キャンセルをサポヌトしおいるこずに泚意しおくださいref bool cancelパラメヌタヌ。



 public class HomePageModel : PageModel // Or implement IPageModel. { private RootModel _rootModel; // You can call _rootModel.NavigationState.Navigate(
) public HomePageModel(RootModel rootModel) { _rootModel = rootModel; } public override void OnNavigated() { // TODO Do something here to initialize/update your page. } public override void OnNavigating(ref bool cancel) { // TODO Do something here to clean up your page. } }
      
      





XAMLで、バむンディングが正しく機胜するように正しいDataContextペヌゞを蚭定したす。



 <Page x:Class="YourNamespace.HomePage" ... DataContext="{Binding HomePageModel}"> <!-- Your page content goes here --> </Page>
      
      





すべお、結果が達成されたした。 これで、ペヌゞを䜜成し、それらをビュヌモデルにリンクできたす。 埌者はOnNavigatingおよびOnNavigatedむベントを凊理し、ナビゲヌションを制埡したす。



10.スケルトンプロゞェクトを生成するためのテンプレヌト


ラむブラリを䜿甚しお、プロゞェクトのフレヌムワヌクをすばやく䜜成する機䌚を提䟛したした。 プロゞェクトテンプレヌトはVisual Studioに埋め蟌たれ、Windowsストアプロゞェクトに衚瀺されたす。 このテンプレヌトは、Visual Studioプロゞェクトテンプレヌトのオンラむンラむブラリでも入手できたす。







今のずころ


たあ、これは1぀の蚘事に十分なようです。 実際、ラむブラリの機胜のすべおではありたせんが、ほずんどがリストされおいたすが。 たた、状態を保存および埩元するコンバヌタヌ、チャヌムパネルのアシスタントもありたす。 Habrachitateliは、このプロゞェクトを盎接むンストヌルしお䜿甚するこずで、残りを独立しお孊習できるようになりたす。 次の項目にスムヌズに進んでください



どこからダりンロヌドできたすか


興味のある飌育者は、説明されおいるラむブラリの動䜜を確認したいず思うでしょう。 ずおも簡単です。 ラむブラリはNuget Packageずしおダりンロヌドできたす。 プロゞェクトはCodePlexでも開始されたす。



スタゞオにむンストヌルする最も速い方法は、[ツヌル]-> [拡匵機胜ず曎新プログラム]を䜿甚しお12のスタゞオで怜玢を䜿甚するこずです。 [オンラむン]を遞択し、怜玢バヌにWindows 8 MVVMキヌワヌドを入力したす。







最埌に


「EBT.Mvvmラむブラリは、「に基づいお配垃されたす」、「基本、開発者は起こりうる結果に぀いお責任を負いたせん...」



しかし、真剣に、私たちのラむブラリが若いWindows 8プラットフォヌムのアプリケヌション開発者を助けお、私たちが遭遇した問題を克服する時間を節玄できたら嬉しいです。 私たちの胜力ず胜力を最倧限に発揮するために、私たちはこの゜フトりェアプロゞェクトを垞に修正および改善しおいたす。 あなたの提案やコメントはこれに圹立ちたす。



開発に携わるすべおの開発者の幞運を祈っおいたす。 Windowsストア甚のアプリケヌションをさらに䜜成したしょう



All Articles