Model View ViewModelãã¿ã¼ã³ï¼ä»¥ä¸MVVMãã¿ã¼ã³ï¼ãç»å ´ãã¦ç´10å¹´ã«ãªãã¾ãã ãããã¸ãã§ä¸åº¦MVVMãå®è£ ããããã§å¿ è¦ã«ãªãæè¡è¦ç´ ãæ¯ãè¿ã£ã¦ã¿ããã¨æãã¾ãã
ãã®åã«MVVM
MVVMã¯ä»¥ä¸ã®Wikipediaãããã§ãè¦ã¦ãã ããã
Model View ViewModel - Wikipedia
è¦ãç®ã¨ããã以å¤ã«ã¯ã©ã¹ãåé¢ãã¦ãããã«è¦ãç®ãXAMLã§ä½ããããããã«Viewã¨ViewModelã«åé¢ãããããªã¤ã¡ã¼ã¸ã§ãã
è¦ã¦ããã
ã¨ãããã¨ã§MVVMã§å¿ è¦ã«ãªãæè¡è¦ç´ ãè¦ã¦ãããã¨æãã¾ãã
INotifyPropertyChangedã¤ã³ã¿ã¼ãã§ã¼ã¹
ã¾ãã¯ããããç¡ãã¨å§ã¾ãã¾ãããMVVMã§ã¯Viewã¯ViewModelãç£è¦ãã¦ãViewModelã¯Modelãç£è¦ãã¦ãããã¨ãå¤ãã§ãããã®æã«ãã¯ã©ã¹ã®ããããã£ãå¤ãã£ããã¨ãéç¥ããããã«C#ã«ç¨æããã¦ããå
±éã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ãSystem.ComponentModel.INotifyPropertyChanged
ã¤ã³ã¿ã¼ãã§ã¼ã¹ã«ãªãã¾ãã
ãã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ã¯PropertyChanged
ã¤ãã³ããæã¤ã ãã®ã·ã³ãã«ãªã¯ã©ã¹ã«ãªãã¾ãããã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ãå®è£
ããã¯ã©ã¹ã§ã¯ãããããã£ã®setterã§PropertyChanged
ã¤ãã³ãã®å¼æ°ã«PropertyChangedEventArgs
ã§ããããã£åã渡ãããã®ã使ã£ã¦ã¤ãã³ããçºç«ãããã¨ã§ãå¤é¨ã«å¯¾ãã¦ããããã£ã®å¤æ´éç¥ãåºæ¥ã¾ãã
ä¾ãã°ã以ä¸ã®ãããªå®è£ ã«ãªãã¾ãã
public class Person : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private string name; public string Name { get { return this.name; } set { this.name = value; this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name))); } } }
以ä¸ã®ãããªã³ã¼ãã§åä½ã確èªã§ãã¾ããããã¯ãXamarinã§ãUWPã§ããªãããã¬ã¼ã³ãªã³ã³ã½ã¼ã«ã¢ããªã±ã¼ã·ã§ã³ã§ãã
public class Program { public static void Main(string[] args) { var p = new Person(); p.PropertyChanged += (_, e) => Console.WriteLine($"{e.PropertyName} changed."); p.Name = "tanaka"; p.Name = "okazuki"; } }
Person
ã¯ã©ã¹ã®ã¤ã³ã¹ã¿ã³ã¹ãä½æãã¦ãPropertyChanged
ã¤ãã³ããè³¼èªãã¦ãã¾ããè³¼èªããå
ã§ã¯å¤æ´ã®ãã£ãããããã£åã表示ãã¦ãã¾ããããã¦ã2åå¤ã代å
¥ãã¦ãã¾ããå®è¡ããã¨ä»¥ä¸ã®ãããªçµæã«ãªãã¾ãã
Name changed. Name changed.
ã¨ã¦ãåç´ã§ãããåç´ãæ ã«ç¡é§ãããã¾ããä¾ãã°ãã³ã¼ãã以ä¸ã®ããã«æ¸ãæãã¦ã¿ã¾ãããã
public class Program { public static void Main(string[] args) { var p = new Person(); p.PropertyChanged += (_, e) => Console.WriteLine($"{e.PropertyName} changed."); p.Name = "tanaka"; p.Name = "tanaka"; } }
å®è¡ããã¨å
ã»ã©ã¨åãããã«2åName changed.
ã表示ããã¾ããå¤ãå¤ãã£ã¦ãªãã®ã«å¤ãå¤ãã£ãã¨è¡¨ç¤ºãããã®ã¯ç¡é§ãªã®ã§ãName
ããããã£ã以ä¸ã®ããã«æ¸ãæãã¾ãã
public class Person : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private string name; public string Name { get { return this.name; } set { // æ¯è¼ãã¦åããªãä½ãããªã if (EqualityComparer<string>.Default.Equals(this.name, value)) { return; } this.name = value; this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name))); } } }
ããã§å®è¡ããã¨ä»¥ä¸ã®ããã«ãªãã¾ãã
Name changed.
ããã§ç¡é§ãªã¤ãã³ãã®çºè¡ããªããªãã¾ããã
å ±éã¯ã©ã¹å
MVVMã§ã¯ãINotifyPropertyChangedãå®è£ ããã¯ã©ã¹ã大éã«ä½æãã¾ãããã®ããããã£ãã¹ã¦ã«ä¸è¨ã®ãããªè¨è¿°ãããã®ã¯åé·ã§ãããã®ããã以ä¸ã®ãããªãã¼ã¹ã¯ã©ã¹ãä½æããã®ãä¸è¬çã§ãã
public class BindableBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null) => this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); protected virtual bool SetProperty<T>(ref T field, T value, [CallerMemberName]string propertyName = null) { if (EqualityComparer<T>.Default.Equals(field, value)) { return false; } field = value; this.OnPropertyChanged(propertyName); return true; } }
ãã®BindableBase
ã¯ã©ã¹ã使ããã¨ã§Person
ã¯ã©ã¹ã¯ä»¥ä¸ã®ããã«ãªãã¾ãã
public class Person : BindableBase { private string name; public string Name { get { return this.name; } set { this.SetProperty(ref this.name, value); } } }
public string Name { get; set; }
ã«æ¯ã¹ãã¨åé·ã§ãããç¾ç¶ãããç²¾ä¸æ¯ã§ãã
XAML
XAMLã¯MVVMãã¿ã¼ã³ã§Viewãè¨è¿°ããã®ã«ä½¿ãã¾ããXAMLã¯XMLããã¼ã¹ã¨ããè¨èªã§é層æ§é ãæã£ããªãã¸ã§ã¯ããçµã¿ç«ã¦ããã¨ã«ç¹åããè¨èªã«ãªãã¾ããåºæ¬çã«ä»¥ä¸ã®ãããªã«ã¼ã«ãããã¾ãã
- XMLåå空éã¯C#ã®åå空éã«å¯¾å¿
- ã¿ã°åã¯ã¯ã©ã¹åã«å¯¾å¿
- å±æ§ã¯ããããã£ã«å¯¾å¿
ä¾ãã°ãXamarinApp.Models
åå空éã«ããPerson
ã¯ã©ã¹ãã¤ã³ã¹ã¿ã³ã¹åãã¦Nameããããã£ã«tanakaã¨è¨å®ããã³ã¼ãã¯C#ã§æ¸ãã¨ä»¥ä¸ã®ããã«ãªãã¨æãã¾ãã
new Person { Name = "tanaka" }
ãããXAMLã§æ¸ãã¨ä»¥ä¸ã®ããã«ãªãã¾ãã
<!-- Xamarin.Formsã®å ´å --> <Models:Person xmlns:Models="clr-namespace:XamarinApp.Models" Name="tanaka" /> <!-- UWPã®å ´å --> <Models:Person xmlns:Models="using:XamarinApp.Models" Name="tanaka" />
XMLåå空éå ã§ã®C#ã®åå空éã®è¨è¿°æ¹æ³ãéã以å¤ã¯åãæ¸ãæ¹ã«ãªãã¾ãã
ããããã£ã®ãã1ã¤ã®æ¸ãæ¹ã¨ãã¦å±æ§ã§ã¯ãªãã¿ã°ã使ç¨ãã¦æ¸ãæ¹æ³ãããã¾ãã
<!-- Xamarin.Formsã®å ´å --> <Models:Person xmlns:Models="clr-namespace:XamarinApp.Models"> <Models:Person.Name>tanaka</Models.Person.Name> </Models:Person> <!-- UWPã®å ´å --> <Models:Person xmlns:Models="using:XamarinApp.Models"> <Models:Person.Name>tanaka</Models.Person.Name> </Models:Person>
ã¯ã©ã¹å.ããããã£å
ã¨ããå½åè¦ç´ã§ã¿ã°ãæ¸ããã¨ã§ããã®ã¿ã°ã®åè¦ç´ ãããããã£ã«è¨å®ããã¾ãããã®æ¸ãæ¹ã®ããã¨ããã¯ãããããã£ã®å¤ã¨ãã¦ãè¤éãªã¯ã©ã¹ãå®ç¾©ã§ããã¨ããç¹ã§ããä¸è¨ã®ä¾ã®ãããªæååã§ã¯ãããããã¿ããããã¾ãããã以ä¸ã®ããã«Personã¯ã©ã¹ã«ãPersonåã®Childããããã£ããã£ã¦ãããã«å¤ãè¨å®ããã¨ãã£ãã¨ãã«å¹æãçºæ®ãã¾ãã
<!-- Xamarin.Formsã®å ´å --> <Models:Person xmlns:Models="clr-namespace:XamarinApp.Models" Name="tanaka"> <Models:Person.Child> <Models:Person Name="kimura" /> </Models:Person.Child> </Models:Person> <!-- UWPã®å ´å --> <Models:Person xmlns:Models="using:XamarinApp.Models" Name="tanaka"> <Models:Person.Child> <Models:Person Name="kimura" /> </Models:Person.Child> </Models:Person>
XAMLã«ã¯ãã³ã³ãã³ãããããã£ã¨ãããã®ããã£ã¦ãã¿ã°ã®ç´ä¸ã«ä½ãæå®ããã«æ¸ããå ´åã¯ãã¯ã©ã¹åä½ã«æå®ãããããããã£ã«å¤ãã»ããããã¨ãããã¨ãåºæ¥ã¾ããä¾ãã°ãä¸è¨ã®ä¾ã§Childããããã£ãã³ã³ãã³ãããããã£ã ã£ãå ´åã以ä¸ã®ããã«ã·ã³ãã«ã«æ¸ããã¨ãåºæ¥ã¾ãã
<!-- Xamarin.Formsã®å ´å --> <Models:Person xmlns:Models="clr-namespace:XamarinApp.Models" Name="tanaka"> <Models:Person Name="kimura" /> </Models:Person> <!-- UWPã®å ´å --> <Models:Person xmlns:Models="using:XamarinApp.Models" Name="tanaka"> <Models:Person Name="kimura" /> </Models:Person>
ããã«ãXAMLã«ã¯ã³ã¬ã¯ã·ã§ã³ã®ããããã£ã«å¯¾ãã¦å¤ãè¨å®ããã¨ãã«ã以ä¸ã®ããã«ã¿ã°ã並ã¹ã¦å®ç¾©ãããã¨ãåºæ¥ã¾ãã
<!-- Xamarin.Formsã®å ´å --> <Models:Person xmlns:Models="clr-namespace:XamarinApp.Models" Name="tanaka"> <Models:Person.Children> <Models:Person Name="kimura1" /> <Models:Person Name="kimura2" /> <Models:Person Name="kimura3" /> <Models:Person Name="kimura4" /> </Models:Person.Children> </Models:Person> <!-- UWPã®å ´å --> <Models:Person xmlns:Models="using:XamarinApp.Models" Name="tanaka"> <Models:Person.Children> <Models:Person Name="kimura1" /> <Models:Person Name="kimura2" /> <Models:Person Name="kimura3" /> <Models:Person Name="kimura4" /> </Models:Person.Children> </Models:Person>
Childrenãã³ã³ãã³ãããããã£ã ã£ãå ´åã¯ã以ä¸ã®ããã«æ¸ããã¨ãã§ãã¾ãã
<!-- Xamarin.Formsã®å ´å --> <Models:Person xmlns:Models="clr-namespace:XamarinApp.Models" Name="tanaka"> <Models:Person Name="kimura1" /> <Models:Person Name="kimura2" /> <Models:Person Name="kimura3" /> <Models:Person Name="kimura4" /> </Models:Person> <!-- UWPã®å ´å --> <Models:Person xmlns:Models="using:XamarinApp.Models" Name="tanaka"> <Models:Person Name="kimura1" /> <Models:Person Name="kimura2" /> <Models:Person Name="kimura3" /> <Models:Person Name="kimura4" /> </Models:Person>
XAMLã«ã¯ããªãã¸ã§ã¯ãã«å¯¾ãã¦ãå¥ã®ãªãã¸ã§ã¯ãã®ããããã£ãè¨å®ããã¨ããæ·»ä»ããããã£ã¨ãããã®ãããã¾ãã ãã®æ·»ä»ããããã£ã¯ãã¬ã¤ã¢ã¦ãã®æ å ±ãã³ã³ããã¼ã«ã«è¿½å ããã¨ãã«ãã使ããã¾ããä¾ãã°ãGridã¨ããæ ¼åç¶ã«é åãåºåã£ã¦ãããã«ã³ã³ããã¼ã«ãç½®ããã¨ãåºæ¥ãã¬ã¤ã¢ã¦ãããã«ãããã¾ãããã®ã¨ããGridã®ä¸ã®è¦ç´ ã«å¯¾ãã¦ä½è¡ä½åç®ã«ç½®ãã¨ããæå®ãããããªãã¾ãããããããããªã±ã¼ã¹ã§æ·»ä»ããããã£ãæ´»èºãã¾ãã
æ·»ä»ããããã£ã¯ãã¯ã©ã¹å.æ·»ä»ããããã£å
ã¨ããå½¢ã§æå®ãã¾ãã
<Grid> <!-- è¡ã¨åã®å®ç¾©ã¯çç¥ --> <Button Grid.Row="0" Grid.Column="1" ... /> <Button Grid.Row="1" Grid.Column="1" ... /> </Grid>
ä¸è¨ã®ä¾ã§ã¯ãæåã®ãã¿ã³ã§ã¯Grid.Rowã¨ããæ·»ä»ããããã£ã¨Grid.Columnã¨ããæ·»ä»ããããã£ã使ã£ã¦ã0è¡1åç®ã«ãã¿ã³ãç½®ãã¨ããæå®ããã¦ãã¾ãããã®ããã«ãGridã®ããããã£ããããããButtonã®ããããã£ã§ãããã®ããã«æå®ã§ããã¨ãããæ·»ä»ããããã£ã®ç¹å¾´ã§ãã
æå¾ã«ãã¼ã¯ã¢ããæ¡å¼µã«ã¤ãã¦èª¬æãã¾ãã ãã¼ã¯ã¢ããæ¡å¼µã¯ããªãã¸ã§ã¯ããçµã¿ç«ã¦ãããã®ã·ã§ã¼ãã«ããã®è¨æ³ã§ããæ®éãªãXMLã®ã¿ã°ã使ã£ã¦çµã¿ç«ã¦ãªãã¨ãããªããããªè¤éãªãªãã¸ã§ã¯ãããå±æ§ã«å¯¾ãã¦æ¸ããããããã¨ãåºæ¥ãããã«ãªãã¾ãã
ãã¼ã¯ã¢ããæ¡å¼µã¯{}
ã§æ¬ããããã®ã«ãªãã¾ããä¾ãã°ãªã½ã¼ã¹ãåç
§ããStaticResource
ãã¼ã¯ã¢ããæ¡å¼µããå¾è¿°ãããã¼ã¿ãã¤ã³ãã£ã³ã°ã§ä½¿ç¨ããBinding
ãã¼ã¯ã¢ããæ¡å¼µãããã¾ãããã¼ã¯ã¢ããæ¡å¼µã使ã£ãã±ã¼ã¹ã¨ä½¿ããªãã±ã¼ã¹ã®æ¯è¼ã®ããã«åãæå³åãã®XAMLãæ¸ãã¦ã¿ã¾ãã
<Label Text="{Binding Name, Mode=OneWay}" /> <Label> <Label.Text> <Binding Path="Name" Mode="OneWay" /> </Label.Text> </Label>
ãã¼ã¿ãã¤ã³ãã£ã³ã°
MVVMã«ããã¦ãViewã¨ViewModelãç´ã¥ããæ¹æ³ã¨ãã¦ãã¼ã¿ãã¤ã³ãã£ã³ã°ã使ããã¾ãããã¼ã¿ãã¤ã³ãã£ã³ã°ããã£ããã¨èª¬æããã¨ãç»é¢ã®ã³ã³ããã¼ã«ã®ããããã£ï¼å³å¯ã«ã¯Xamarin.Formsã§ã¯ãã¤ã³ããã«ããããã£ãUWPã§ã¯ä¾åé¢ä¿ããããã£ï¼ã¨ãæ®éã®ã¯ã©ã¹ã®ãªãã¸ã§ã¯ãã®ããããã£ã®åæãã¨ãä»çµã¿ã§ãã
Xamarin.Formsã§ã¯ãBindableObject
ã§å®ç¾©ãããBindingContext
ããããã£ã«è¨å®ããããªãã¸ã§ã¯ããBinding
ã®Path
ã®èµ·ç¹ã«ãªãã¾ããUWPã§ã¯ãFrameworkElement
ã§å®ç¾©ãããDataContext
ããããã£ã«è¨å®ããããªãã¸ã§ã¯ããBinding
ã®Path
ã®èµ·ç¹ã«ãªãã¾ãã
Path
ã®èµ·ç¹ã«ãªãã¨ã¯ä»¥ä¸ã®ãããªåä½ã®ãã¨ã§ãã
ä¾ã¨ãã¦Person
ã¯ã©ã¹ããã¤ã³ããã¦ã¿ã¾ãã
// ãã£ãå®ç¾©ããBindableBaseã¯ã©ã¹ãä½¿ç¨ public class Person : BindableBase { private string name; public string Name { get { return this.name; } set { this.SetProperty(ref this.name, value); } } }
Xamarin.Formsã§ã¯ã以ä¸ã®ããã«ãªãã¾ãã
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:Models="clr-namespace:XamarinApp.Models" x:Class="XamarinApp.Views.MainPage"> <ContentPage.BindingContext> <Models:Person Name="tanaka" /> </ContentPage.BindingContext> <StackLayout> <Entry Text="{Binding Name, Mode=TwoWay}" /> <Label Text="{Binding Name, Mode=OneWay}" /> </StackLayout> </ContentPage>
UWPã§ã¯ã以ä¸ã®ããã«ãªãã¾ãã
<Page x:Class="UWPApp.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:UWPApp" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:Models="using:UWPApp.Models" mc:Ignorable="d"> <Page.DataContext> <Models:Person Name="kimura" /> </Page.DataContext> <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <TextBox Text="{Binding Name, Mode=TwoWay}" /> <TextBlock Text="{Binding Name, Mode=OneWay}" /> </StackPanel> </Page>
ãã®ããã°ã©ã ãå®è¡ãããã¨ã§ãå
¥åããå¤ããä¸ã®ããã¹ãã«Person
ã¯ã©ã¹ã®Name
ããããã£ãçµç±ãã¦åæããã¾ãããã®ã¨ãã®å¤ã®å¤æ´ã¿ã¤ãã³ã°ã®æ¤ç¥ã«ã¯ãæåã«éè¨ããINotifyPropertyChanged
ã¤ã³ã¿ã¼ãã§ã¼ã¹ã使ç¨ããã¦ãã¾ãã
Bindingã«ã¯ãModeãããã¾ããModeã«ã¯ä»¥ä¸ã®ãããªãã®ãããã¾ãã
- OneWay: ã½ã¼ã¹ï¼C#ã®ãªãã¸ã§ã¯ãï¼ããã¿ã¼ã²ããï¼ç»é¢ã®ã³ã³ããã¼ã«å´ï¼ã¸ã®1æ¹ååæ
- TwoWay: ã½ã¼ã¹ã¨ã¿ã¼ã²ããã®åæ¹ååæ
- OneTime: ã½ã¼ã¹ããã¿ã¼ã²ããã¸ã®1度ããã®åæ
æå®ããªãå ´åã¯ãããã©ã«ãã§OneWayã«ãªãã¾ãã
UWPåºæã®æ©è½
UWPåºæã®æ©è½ã¨ãã¦ã³ã³ãã¤ã«æãã¼ã¿ãã¤ã³ãã£ã³ã°ã¨ãããã®ãããã¾ããããã§ã¯è©³ããè¿°ã¹ã¾ãããã以ä¸ã®è¨äºãåç §ãã¦ã¿ã¦ãã ããã
ã³ãã³ã
Viewã§èµ·ããã¤ãã³ããViewModelã«ä¼ããæ段ã¨ãã¦Commandã¨ãããã®ãç¨ãããã¾ããCommandã®å®æ ã¯ãICommandã¤ã³ã¿ã¼ãã§ã¼ã¹ã¨ãããèªèº«ãå®è¡å¯è½ãã©ããã¨ããç¶æ ã¨ãå®è¡ããã¨ããExecuteã¡ã½ãããæã£ãã ãã®ã·ã³ãã«ãªã¤ã³ã¿ã¼ãã§ã¼ã¹ã«ãªãã¾ãã
public interface ICommand { event EventHandler CanExecuteChanged; bool CanExecute(object parameter); void Execute(object parameter); }
Executeã¡ã½ããã¨CanExecuteã¡ã½ãããããªã²ã¼ãã§æå®å¯è½ãªä»¥ä¸ã®ãããªDelegateCommandã¨ããã¯ã©ã¹ãå®ç¾©ãã¦ä½¿ãã®ãä¸è¬çã§ãã
using System; using System.Windows.Input; namespace UWPApp { public class DelegateCommand : ICommand { public event EventHandler CanExecuteChanged; private Func<bool> canExecute; private Action execute; public DelegateCommand(Action execute, Func<bool> canExecute = null) { this.execute = execute; this.canExecute = canExecute; } public bool CanExecute(object parameter) => this.canExecute?.Invoke() ?? true; public void Execute(object parameter) => this.execute(); public void RaiseCanExecuteChanged() => this.CanExecuteChanged?.Invoke(this, EventArgs.Empty); } }
Xamarin.Formsã§ã¯ãä½æ
ãICommandã®å®è£
ã¯ã©ã¹ã§ããXamarin.Forms.Command
ã¯ã©ã¹ãæä¾ããã¦ããã®ã§èªåã§å®è£
ããå¿
è¦ã¯ããã¾ããã
Commandã使ç¨ããã¯ã©ã¹ä¾ãè¦ã¦ã¿ã¾ããMainPageã«å¯¾å¿ããViewModelã§ããMainPageViewModelã¨ããã¯ã©ã¹ã以ä¸ã®ããã«å®ç¾©ãã¾ãã
// Xamarin.Forms using System; using Xamarin.Forms; using XamarinApp.Models; namespace XamarinApp.ViewModels { public class MainPageViewModel : BindableBase { private string now; public string Now { get { return this.now; } set { this.SetProperty(ref this.now, value); this.UpdateNowCommand.ChangeCanExecute(); } } public Command UpdateNowCommand { get; } public MainPageViewModel() { this.UpdateNowCommand = new Command(() => { this.Now = DateTime.Now.ToString(); }, () => string.IsNullOrEmpty(this.Now)); } } }
// UWP using System; using UWPApp; using UWPApp.Models; namespace UWPApp.ViewModels { public class MainPageViewModel : BindableBase { private string now; public string Now { get { return this.now; } set { this.SetProperty(ref this.now, value); this.UpdateNowCommand.RaiseCanExecuteChanged(); } } public DelegateCommand UpdateNowCommand { get; } public MainPageViewModel() { this.UpdateNowCommand = new DelegateCommand(() => { this.Now = DateTime.Now.ToString(); }, () => string.IsNullOrEmpty(this.Now)); } } }
Commandã¯ãButtonã¯ã©ã¹ãæã£ã¦ããCommandããããã£ã¨ãã¼ã¿ãã¤ã³ãã£ã³ã°ãããã¨ã§ãã¦ã¼ã¶ã¼ã®æä½ãCommandã«æ¸¡ããã¨ãã§ãã¾ããXAMLãæ¸ãã¦ã¿ã¾ãããã
<!-- Xamarin.Forms --> <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:ViewModels="clr-namespace:XamarinApp.ViewModels" x:Class="XamarinApp.Views.MainPage"> <ContentPage.BindingContext> <ViewModels:MainPageViewModel /> </ContentPage.BindingContext> <StackLayout> <Button Text="Update now" Command="{Binding UpdateNowCommand}" /> <Label Text="{Binding Now}" /> </StackLayout> </ContentPage>
å®è¡ããã¨ã以ä¸ã®ããã«ãªãã¾ããã¾ãããã¿ã³ã ãã表示ããã¾ãã
ãã¿ã³ãæ¼ãã¨ãç¾å¨æå»ã表示ãããã¿ã³ãæ¼ããªããªãã¾ãã
ããã¯Commandã®ç¬¬äºå¼æ°ã§Nowã空ã®æããæ¼ããªãã¨ããæ¡ä»¶ãæå®ãã¦ããããã§ããã¾ããCommandã®ç¶æ ãå¤ãã£ããã¨ãéç¥ããããã«Nowããããã£ã®setterã§ã³ãã³ãã®å¤æ´ã¤ãã³ããçºè¡ãã¦ããããUIã¨ã®åæãã¨ããã¦ãã¾ãã
UWPå´ãXAMLãè¦ã¦ã¿ã¾ãããã大ä½åãã§ãã
<Page x:Class="UWPApp.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:UWPApp" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ViewModels="using:UWPApp.ViewModels" mc:Ignorable="d"> <Page.DataContext> <ViewModels:MainPageViewModel /> </Page.DataContext> <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Button Content="Update now" Command="{Binding UpdateNowCommand}" /> <TextBlock Text="{Binding Now}" /> </StackPanel> </Page>
å®è¡çµæãåãã«ãªãã¾ãã
Modelã¨ViewModelé
MVVMã§VMã¨Vã®éã®é£æºã¯ããã£ãã®ã§Modelã¨ViewModelã¯ã©ããªã®ï¼ã¨ããçåãæã¤ããããã¾ããã
ããã¯é常ã®C#ã®ããã°ã©ãã³ã°ã«ãªãã¾ããã¡ã½ããå¼ã³åºããã¡ã½ããã®æ»ãå¤ãã¤ãã³ããªã©ãé©åã«ä½¿ã£ã¦å®è£ ãããã¨ã«ãªãã¾ãã
ããã§æ¸ãã¦ãªããã©å¿ ãã¶ã¤ãããã®
- ã³ã¬ã¯ã·ã§ã³ã®ãã¤ã³ãã©ãããã®ï¼âINotifyCollectionChangedã®å®è£ ã¯ã©ã¹ã§ããObservableCollectionã使ã£ã¦ListViewãªã©ã®ãªã¹ã表示系ã³ã³ããã¼ã«ã使ã
- ViewModelããViewã«ä½ãéç¥ãããããã ãã©âã¡ãã»ã³ã¸ã£ã¼ãã¿ã¼ã³ã¨ãããã®ãããã¾ãã
ã¾ã¨ã
ã ãã ãã¨æ¸ãã¾ããããã¾ã¨ãã¨ãã¦ã¯â¦ã ä½ããã¬ã¼ã ã¯ã¼ã¯ã使ãã¾ããããå人çã«ã¯Prismãããããã§ããããã§å®è£ ãããããªBindableBaseã¯ã©ã¹ãDelegateCommandã¯ã©ã¹ãæä¾ããã¦ããä»ã«ãç»é¢é·ç§»ããã¤ã¢ãã°ã®è¡¨ç¤ºãªã©å®éã®ã¢ããªãä½ãããã§ä¾¿å©ãªæ©è½ãæä¾ããã¦ãã¾ããXamarin.Formsã®Prismã«ã¤ãã¦ã¯æ¸ãã¦ãªãã§ããããã¡ãã®ãªãã¸ããªã«WPFã¨UWPã®Prismã«ã¤ãã¦ã¯æ¸ãã¦ããããã¾ãã
Xamarin.Formsçã®Prismã«ã¤ãã¦ã¯ä»¥ä¸ã®Blogã詳ããã§ãã
ã¾ããã¾ã æ£å¼ãªãªã¼ã¹åã«Prismã«ã¤ãã¦çºè¡¨ããè³æã¨ããããã¾ãã
www.slideshare.net