ã³ã³ããã¹ãã¢ãã«ãã¿ãŒã³ -MVVM ã
MVP ã
MVCã¢ãŒããã¯ãã£ãã¿ãŒã³ã®æ©èœãçµã¿åãããã¢ããªã±ãŒã·ã§ã³èšèšã³ã³ã»ããã§ãããããªãèªç±ã§é²æ©çãªãé©åã«èª¿æŽãããäžé£ã®ããããžã§ãã³ã°ã«åºã¥ããŠããŸãã ç€ç³ã¯
è¡šçŸ ã
調åè
ã
æèã®ãªããžã§ã¯ããš
ãããã®ã³ã¬ã¯ã·ã§ã³ã§ãããåºæ¬çãªæšèŠã¯
çŽæ¥æ³šå°ã®åçã§ã ã
Aeroãã¬ãŒã ã¯ãŒã¯ã¯ãåé¡ã®ãã¿ãŒã³ã«äžèŽããxamlæåã®ã¢ããªã±ãŒã·ã§ã³ãäœæããããã«å¿
èŠãªãã¹ãŠã®ã€ã³ãã©ã¹ãã©ã¯ãã£ãå«ã
CïŒèšèªã®ãªãŒãã³ã©ã€ãã©ãªã§ãã é©åã«äœ¿çšããããšã§ããœãŒã¹ã³ãŒãã¯ãåå¿è
éçºè
ã«ãšã£ãŠãåäŸã®ãªãã»ã©ç°¡æœã§ã髿§èœã§ãçŽæçã§ãã
ãã¿ãŒã³ã®ã¢ã€ãã¢ã«åŸãããšã§ãã¢ããªã±ãŒã·ã§ã³ã®ããã²ãŒã·ã§ã³ãšããŒã«ãªãŒãŒã·ã§ã³ããããŒã¿æ€èšŒã¡ã«ããºã ã®å®è£
ãŸã§ãå€ãã®æ¥åžžçãªã¿ã¹ã¯ãçŸããèªç¶ã«è§£æ±ºããã€ã³ã¿ãŒãã§ã€ã¹ãšè«çãã¥ãŒã¢ãã«ã®èŠèŠçç¶æ
ãç¶æã§ããŸãã ããããæãéèŠãªããšã¯ãæç¢ºã§æåããéåžžã«ã·ã³ãã«ãªã¢ãŒããã¯ãã£ãæ§ç¯ããã®ã«åœ¹ç«ã€ããšã§ãã ããã«ãéçºã®é床ãšå質ã倧å¹
ã«åäžããèšè¿°ãããã³ãŒãã®éãæ°ååæžããã
ããŸããŸãªãããžã§ã¯ãã§æ£åžžã«ãã¹ããã
ãŠããŸã ã
æ°é
ãã®ããæ£è
ã®èªè
ã«ã¯ãç¥èãgeneãã¿ãªãäžããããŸãã
ã³ã³ããã¹ãåºç€ã®åçïŒ ã³ã³ããã¹ãåºç€ã®åå ïŒãã¥ãŒã¯ãã³ã³ããã¹ããªããžã§ã¯ãã®ç¹å®ã®ã€ã³ã¹ã¿ã³ã¹ãèŠèŠåããæ¹æ³ãèšè¿°ããã€ã³ã¿ãŒãã§ã€ã¹ããŒã¯ã¢ãããã³ãã¬ãŒãã§ãã åèªãããã¹ããã€ã³ãããŒã·ã§ã³ããŸãã¯ç¶æ³ïŒã€ãŸãã³ã³ããã¹ãïŒå
ã§æå³çãªæå³åããç²åŸããããã«ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®èŠèŠèŠçŽ ã¯ãã³ã³ããã¹ããªããžã§ã¯ããšå¯æ¥ã«é¢é£ããå Žåã«ã®ã¿æçã«ãªããŸããèšãæãããšããŠãŒã¶ãŒãã¬ã³ããªãŒãªåœ¢åŒã§ã³ã³ããã¹ãã«å«ãŸããæçšãªããŒã¿ã衚瀺ãå§ããŸãã
ä»»æã®ã¿ã€ãã®ã€ã³ã¹ã¿ã³ã¹ã¯ã³ã³ããã¹ããªããžã§ã¯ããšããŠæ©èœã§ããŸããã³ã³ããã¹ããªããžã§ã¯ãã«å«ãŸããæ
å ±ã®è§£éæ¹æ³ãç¥ãå¿
èŠãããã®ã¯ããã¥ãŒèªäœã ãã§ãã ãããŠãã¢ã€ãã¢èªäœã§ãããããèªäœã®ã³ã³ããã¹ããŸãã¯å¥ã®ã¢ã€ãã¢ã«ãªãããšãã§ããŸãã ããã«ã衚çŸã¯ãã«ãã³ã³ããã¹ãã«ããããšãã§ããŸããã€ãŸããè€æ°ã®ãœãŒã¹ãªããžã§ã¯ãããã®æ
å ±ãåæã«äœ¿çšã§ããŸãã
ã€ãŸãããšã³ããŠãŒã¶ãŒã«ãšã£ãŠã¯ããã¬ãŒã³ããŒã·ã§ã³ã³ã³ããã¹ããªããžã§ã¯ãã®æã ããæå³ããªããŸãã åå¥ã®ãã¬ãŒã³ããŒã·ã§ã³èªäœã¯å®çšçãªèгç¹ããã¯ç¡æå³ã§ããããŠãŒã¶ãŒã¯ãªããžã§ã¯ããéèŠèŠçãªåœ¢ã§ç¥èŠããããšã¯ã§ããŸããã ãªããžã§ã¯ãã衚çŸãšäžèŽãããšã
ã³ã³ããã¹ãã®åºæ¬æ§ã®ããããã£ãååŸããã衚çŸã¯
æçã«ãªã
ãŸã ã
CM-ãã¿ãŒã³ã«ã¯ã次ã®åºæ¬çãªèŠå®ãå«ãŸããŸãã
â¢1ã€ãŸãã¯è€æ°ã®ã³ã³ããã¹ããªããžã§ã¯ãïŒããã³ãã®éïŒãä»»æã®è¡šçŸã«é¢é£ä»ããããšãã§ããŸãïŒå€å¯Ÿå€ã®é¢ä¿ïŒã 衚çŸãšã³ã³ããã¹ããªããžã§ã¯ãã®çžäºäœçšã¯ã3çš®é¡ã®ã¡ãã£ãšãŒã¿ãŒãä»ããŠçºçããŸããããããã£ãã³ãã³ããã³ã³ããã¹ãã€ã³ãžã§ã¯ã·ã§ã³ã®ãã€ã³ãã
â¢ãã¥ãŒã¢ãã«ãšã¢ãã«ã¯ç°ãªãç¹æ§ãæã€ãšã³ãã£ãã£ã§ãããäžè¬çãªãã¡ã€ã³ã¢ããªã³ã°æ©èœãå®è¡ããã³ã³ããã¹ãåºæ¬ã®ããããã£ãæã£ãŠããããã1ã€ã®åºæ¬ã¯ã©ã¹ãã¢ãã«ãšãã¥ãŒã¢ãã«ã®äž¡æ¹ã«é©çšããããšã¯ãŸã£ããåãå
¥ããããŸããè€éãªè¡šçŸèªäœã¯ãèŠèŠçããªãŒã®èŠçŽ ã§ãããããå°ããåºæ¬çãªè¡šçŸã§æ§æãããŠããŸãã ç¹å¥ãªçš®é¡ã®ã«ãŒããã¥ãŒã¯ãäœããã®åœ¢åŒã§ã®ããã²ãŒã·ã§ã³ããµããŒããã
ç»é¢ã§ãã
ãã¬ãŒã³ããŒã·ã§ã³ãšã³ã³ããã¹ããªããžã§ã¯ãã®çžäºäœçšã¯ã ã¡ãã£ãšãŒã¿ãŒãä»ããŠçºçããŸãã ããã¯ãããžãã¹ããžãã¯ãã€ã³ã¿ãŒãã§ã€ã¹ããžãã¯ããç°¡åã«åé¢ã§ãããããéåžžã«éèŠãªãã€ã³ãã§ãããã®éèŠæ§ã¯ãå€ãã®å Žåã衚çŸã®åç¶æéãã³ã³ããã¹ããªããžã§ã¯ãïŒãã¥ãŒã¢ãã«ãªã©ïŒã®åç¶æéãããçãããšãããã³å¯èœã§ããã°ãæ£ããå®è£
ãããã¡ãã£ãšãŒã¿ãŒã«ã¯ã匱ããµãã¹ã¯ãªãã·ã§ã³ãšãçžäºäœçšãããªããžã§ã¯ããžã®ãªã³ã¯ã®ã¿ãå«ãŸããŠããããšã§ããã¡ã¢ãªãªãŒã¯ããä¿è·ããŸãã
ã¡ãã£ãšãŒã¿ãŒã¯ã3ã€ã®äž»èŠãªæ©èœãå®è¡ããŸãã
â¢ããããã£ãã€ã³ãã£ã³ã°ïŒ
Binding ã
StoreBinding ïŒ
â¢ãã€ã³ãã£ã³ã°ã³ãã³ãïŒ
ã³ã³ããã¹ã ïŒ
â¢ã³ã³ããã¹ãã€ã³ãžã§ã¯ã·ã§ã³ïŒ
ã¹ã㢠ïŒ
xamlã«é¢ããŠããã¥ãŒã«ã¯åå¥ã®ããŒã¯ã¢ããããŒãžãš
ã³ã³ãããŒã«ãã³ãã¬ãŒãããã³
ããŒã¿ãã³ãã¬ãŒãã®äž¡æ¹ãå«ãŸããŸãã ãããã«ããã
è€éãªè¡šçŸèªäœã¯ãããå°ããããåºæ¬çãªè¡šçŸ-èŠèŠçãªããªãŒã®èŠçŽ ã§æ§æãããŸã ã
äŸãèããŠã¿ãŸãããïŒ
[DataContract]
public class PersonsViewModel : ViewModelBase { public ObservableCollection<Person> Persons { get; set; }
<ListBox ItemsSource={Binding Persons}> <ListBox.ItemTemplate> <DataTemplate> <StackPanel> <TextBlock Text="{Binding FirstName}"/> <TextBlock Text="{Binding LastName}"/> </StackPanel> </DataTemplate> <ListBox.ItemTemplate> </ListBox>
ããã§ã¯ã
Personãšã³ãã£ãã£ã¢ãã«ã®ã³ã¬ã¯ã·ã§ã³ãã€ã³ã¿ãŒãã§ã€ã¹èŠçŽ ã«æ·»ä»ãããã¢ãã«ããŒã¿ãã€ã³ã¿ãŒãã§ã€ã¹ã«çŽæ¥è¡šç€ºãããŸãã å¥ã®ç¶æ³ïŒ
public class TextDocumentViewModel : ViewModelBase { public string FileName { get; set; } public string Text { get; set; }
public class DocumentsViewModel : ViewModelBase { public ObservableCollection<TextDocumentViewModel> Documents { get; set; }
<TabControl ItemsSource={Binding Persons} ItemTemplate={Binding FileName, Converter={StaticResource TitleConverter}}> <TabControl.ContentTemplate> <DataTemplate> <StackPanel> <TextBox AcceptsTab="True" AcceptsReturn="True" Text="{Binding Text, Mode=TwoWay}"/> </StackPanel> </DataTemplate> <TabControl.ContentTemplate> </TabControl>
TextDocumentViewModelã¯
Textã¢ãã«ãš
FileNameã¢ãã«ã®ããŒã¿ãéçŽããŸãã
ã€ãŸã ãå®éã«ã¯ã¢ãã«ã§ããããŸããã
ViewModelBaseã¯ã©ã¹ããç¶æ¿ãããŸãããã©ã¡ãã®å Žåã
Personãš
TextDocumentViewModelã¯
DataTemplateã®ããŒã¿ã³ã³ããã¹ããªããžã§ã¯ãã§ãã
ããããããã¯ãéåžžæ³å®ãããããããã¥ãŒã¢ãã«ãšã¢ãã«ã®é¡äŒŒæ§ããŸã ããããšã瀺ããŠããªãã®ã§ããããïŒ ModelBaseãšViewModelBaseãåäžã®Entity ContextObjectã«äžè¬åãããšã©ããªããŸããïŒåæ§ã®ãªããžã§ã¯ããæã€ã¹ãããããã£ãèŠãŠã¿ãŸãããã
ViewModelBaseã¯ãååãšããŠã
äœããã®æ¹æ³ã§
INotifyPropertyChangedã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ããŠãããããã£å€ã®å€æŽã«ã€ããŠã€ã³ã¿ãŒãã§ã€ã¹èŠçŽ ã«éç¥ããŸãã
ModelBaseã¯ãã®ã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ããããšããããéåžž
ã¯ã·ãªã¢ã«åããµããŒãããŸã ã ãã®æ©èœã¯ãã¹ãŠ
ContextObjectã¯ã©ã¹ã«ãã£ãŠå®è£
ããããããå¯èœã§ããã°ããã¥ãŒã¢ãã«ã ãã§ãªãã¢ãã«èªäœã®åºç€ãšããŠäœ¿çšããããšããå§ãããŸãã
ãã®ãããªæšå¥šäºé
ã¯äžèŠå¥åŠã«èŠãããããããŸããããæ·±ãèãããšããã¹ãŠãéåžžã«èªç¶ã§ãããã¥ãŒã¢ãã«ãšã¢ãã«ã®å®éã®ç®çã®éãã«ããããããããããã¯ããŒã¿ã³ã³ããã¹ãã®ãªããžã§ã¯ãïŒã³ã³ããã¹ããªããžã§ã¯ãïŒã§ãããããå
±éã®åºç€ãæã£ãŠããå¯èœæ§ãé«ãããã§ãã ããã«ããã¥ãŒã¢ãã«ã«éå®åã®ã·ãªã¢ã«åã¡ã«ããºã ã䜿çšãããšã以äžã«ç€ºãããã«ãåºç¯å²ã®äžè¬çãªã¿ã¹ã¯ãéåžžã«çŸãã解決ã§ããŸãã
ããã«ã
CMãã¿ãŒã³ã®åºæ¬ã¯è¿œå ã®æšå¥šäºé
ã®ã»ããã§ãããããã«ã€ããŠèª¬æããŸãã
ã·ã³ãã«ããã¢ãŒããã¯ãã£ãæåããã鵿åã®ã»ã¯ã·ã§ã³ã§ã¯ãçŽ æãžã®èªè
ã®é¢å¿ãåèµ·ããåºæ¬ã«ã€ããŠã®å
¥éæŠå¿µã瀺ãããã«ã
Aero Frameworkã©ã€ãã©ãªïŒ
ã¢ããªã±ãŒã·ã§ã³äŸã®ãœãŒã¹ã³ãŒã ã
Webãµã€ã ïŒã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããäžè¬çãªã¹ããŒã ã瀺ããæ¬¡ã®éèŠãªåé¡ã®ãµãŒã¯ã«ãç°¡åã«èª¬æããŸãã
â¢
çŽæ¥æ³šå
¥ã®åç ïŒ
çŽæ¥æ³šå
¥ã®åç ïŒ
â¢
Exposableãã¿ãŒã³ãä»ããç¬ç«ããæ³šå
¥â¢
ã³ãã³ãæåããã²ãŒã·ã§ã³â¢åçããŒã«ãªãŒãŒã·ã§ã³ïŒ
åçããŒã«ã©ã€ãº ïŒ
â¢ã³ã³ããã¹ãã³ãã³ããšããªã¬ãŒïŒ
ã³ã³ããã¹ãã³ãã³ããšããªã¬ãŒ ïŒ
â¢ããããã£ã®éç¥ãšæ€èšŒïŒ
ããããã£ã®éç¥ãšæ€èšŒ ïŒ
â¢ãã¹ããŒããç¶æ
ïŒ
ã¹ããŒãç¶æ
ïŒ
ã€ã³ã¿ãŒããããã³ãã³ã°ã®æ©èœã®äžéšãã€ãŸããæ¿èªç»é¢ãšãã¢ã«ãŠã³ããšéè¡ã«ãŒãã䜿çšãããŠãŒã¶ãŒè£œåã«é¢ããæ
å ±ãäœæããŸãã
CMãã¿ãŒã³ã«ããã°ããããžã§ã¯ãã«ã¯äžé£ã®ããã²ãŒãå¯èœãªãã¥ãŒïŒç»é¢ïŒãšãããã®ãã¥ãŒã¢ãã«ãå«ãŸããŠããŸãã
ããã«ãç¹å®ã®ãã¥ãŒã¢ãã«ã§ã¯è€æ°ã®ç»é¢ããããããã€ãã®ç»é¢ã¯åæã«è€æ°ã®ãã¥ãŒã¢ãã«ã§åäœã§ããŸãã
LoginViewModelãš
ProductsViewModelãäœæãã
ContextObjectã¯ã©ã¹ãš
IExposableã€ã³ã¿ãŒãã§ã€ã¹ããããããç¶æ¿ããŸãããŸãããŠãŒã¶ãŒãæ¿èªãã
LoginView ãéžæãã補åã®ãªã¹ããå«ã
ProductsView ãéžæãã補åãšãã®ã¢ã¯ã·ã§ã³ã®ã»ããã«é¢ãã詳现æ
å ±ãå«ã
ProductViewãäœæããŸãã
[DataContract] public class LoginViewModel : ContextObject, IExposable { [DataMember] public string Name { get { return Get(() => Name); } set { Set(() => Name, value); } } public string Password { get { return Get(() => Name); } set { Set(() => Name, value); } } public UserData UserData { get { return Get(() => UserData); } set { Set(() => UserData, value); } } public virtual void Expose() { this[() => Name].PropertyChanged += (sender, args) => Context.Login.RaiseCanExecuteChanged(); this[() => Password].PropertyChanged += (sender, args) => Context.Login.RaiseCanExecuteChanged(); this[() => Name].Validation += () => Error = Name == null || Name.Length < 3 ? Unity.App.Localize("InvalidName") : null; this[() => Password].Validation += (sender, args) => Error = Name == null || Name.Length < 4 ? Unity.App.Localize("InvalidPassword") : null; this[Context.Login].CanExecute += (sender, args) => { args.CanExecute = string.IsNullOrEmpty(Error);
<View DataContext="{Store Key=viewModels:LoginViewModel}"> <StackPanel> <TextBlock Text="{Localizing Key=Name}"/> <TextBox Text="{Binding Name, Mode=TwoWay}"/> <TextBlock Text="{Localizing Key=Password}"/> <PasswordBox Password="{Binding Password, Mode=TwoWay}"/> <Button Command="{Context Key=Login}" CommandParameter="{x:Type ProductsView}" Content="{Localizing Key=Login}"/> <TextBlock Text="{Binding Error}"/> </StackPanel> </View>
public class ProductsViewModel : ContextObject, IExposable { public Product CurrentProduct { get { return Get(() => CurrentProduct); } set { Set(() => CurrentProduct, value); } } public ContextSet<Product> Products { get; set; } public virtual void Expose() { Products = new ContextSet<Product>(); this[() => Name].PropertyChanged += (sender, args) => Context.Login.RaiseCanExecuteChanged(); this[() => Password].PropertyChanged += (sender, args) => Context.Login.RaiseCanExecuteChanged(); this[() => CurrentProduct].PropertyChanged += (sender, args) => Context.Get("GoToProduct").RaiseCanExecuteChanged(); this[Context.Get("GoToProduct")].CanExecute += (sender, args) => args.CanExecute = CurrentProduct != null; this[Context.Get("GoToProduct")].Executed += (sender, args) => Navigator.GoTo(args.Parameter); this[Context.Refresh].Executed += async (sender, args) => { try { var products = await Bank.Current.GetProducts(); CurrentProduct = null; Products.Clean(); products.ForEach(p => Products.Add); } catch (Exception exception) { Error = Unity.App.Localize(exception.Message); } }; } }
<View DataContext="{Store Key=viewModels:ProductsViewModel}"> <Attacher.ContextTriggers> <ContextTrigger EventName="Loaded" UseEventArgsAsCommandParameter="False" Command="{Context Key=Refresh, StoreKey=viewModels:ProductsViewModel}"/> </Attacher.ContextTriggers> <StackPanel> <StackPanel DataContext="{Store Key=viewModels:LoginViewModel}"> <TextBlock Text="{Localizing Key=UserName}"/> <TextBlock Text="{Binding Path=UserData.FullName}"/> <Button Command="{Context Key=Logout}" CommandParameter="{x:Type LoginView}" Content="{Localizing Key=Logout}"/> </StackPanel> <ListBox ItemsSource="{Binding Products}" SelectedItem="{Binding CurrentProduct, Mode=TwoWay}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel> <TextBlock Text="{Binding Name}"/> <TextBlock Text="{Binding Balance, StringFormat=D2}"/> <TextBlock Text="{Binding CurrencyCode}"/> <StackPanel Visibility="{StoreBinding StoreKey=viewModels:SettingsViewModel, Path=ShowDetails, Converter="{StaticResource TrueToVisibleConverter}"}"> <TextBlock Text="{Localizing Key=ExpireDate}"/> <TextBlock Text="{Binding ExpireDate}"/> </StackPanel> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> <Button Content="{Localizing Key=Next}" Command="{Context Key=GoToProduct}" CommandParameter="{x:Type ProductView}"/> <StackPanel> </View>
<View DataContext="{Store Key=viewModels:ProductsViewModel}"> <StackPanel DataContext="{Binding CurrentProduct}"> <TextBlock Text="{Binding Name}"/> <TextBlock Text="{Binding Balance, StringFormat=D2}"/> <TextBlock Text="{Binding CurrencyCode}"/> <TextBlock Text="{Localizing Key=ExpireDate}"/> <TextBlock Text="{Binding ExpireDate}"/> <StackPanel DataContext="{Store Key=viewModels:NavigatorViewModel}"> <Button Content="{Localizing Key=MakePayment}" Command="{Context Key=Navigate}" CommandParameter="{x:Type PaymentView}"/> <Button Content="{Localizing Key=MakeTransfer}" Command="{Context Key=Navigate}" CommandParameter="{x:Type TransferView}"/> </StackPanel> </StackPanel> </View>
ããã§ã¯ãããã§éèŠãªãã€ã³ãã«æ³šç®ããŸãããã
1ïŒ çŽæ¥æ³šå
¥ã®åç ïŒ çŽæ¥æ³šå
¥ã®åç ïŒãã¥ãŒã¢ãã«ãšãã¥ãŒã®ãªã³ã¯ã¯ã
Binding / Markup Extensionsã䜿çšããŠã³ã³ããã¹ããªããžã§ã¯ããçŽæ¥æ³šå
¥ããããšã«ããã
xamlã§çŽæ¥è¡ãã
ãŸã ã
DataContext="{Store Key=viewModels:ProductsViewModel}" Visibility="{StoreBinding StoreKey=viewModels:SettingsViewModel, Path=ShowDetails, Converter="{StaticResource TrueToVisibleConverter}"}"
ãã©ãããã©ãŒã ïŒ
Windowsãã¹ã¯ãããã
Windows Phoneãªã©ïŒã«å¿ããŠãããŒã¯ã¢ããããŒãµãŒã®å®è£
ã®è©³çްã«ãã£ãŠæ§æãç°ãªãå ŽåããããŸãããååã¯åãã§ãã
Windowsãã¹ã¯ãããã§ã¯ãæ¬¡ã®æ¹æ³ã§èšè¿°ã§ããŸãã
DataContext="{Store viewModels:ProductsViewModel}" DataContext="{Store Key=viewModels:ProductsViewModel}" Visibility="{StoreBinding Path=ShowDetails, KeyType=viewModels:SettingsViewModel, Converter="{StaticResource TrueToVisibleConverter}" Visibility="{StoreBinding ShowDetails, KeyType=viewModels:SettingsViewModel, Converter="{StaticResource TrueToVisibleConverter}"}" Visibility="{Binding ShowDetails, Source={Store viewModels:SettingsViewModel}, Converter="{StaticResource TrueToVisibleConverter}"}"
Windows Phoneã§ã¯ããã®ãã¥ãŒã®ã¿ãèš±å¯ãããŸãã
DataContext="{m:Store Key=viewModels:ProductsViewModel}" Visibility="{m:StoreBinding StoreKey=viewModels:SettingsViewModel, Path=ShowDetails, Converter="{StaticResource TrueToVisibleConverter}"
CïŒã³ãŒãã®æ§æã¯éåžžã«åçŽã«èŠããŸãã
var anyViewModel = Store.Get<AnyViewModel>();
ã€ã³ãžã§ã¯ã·ã§ã³ã¯
DataContextã³ã³ãããŒã«ã ãã§ãªãã
Bindingã§ãçŽæ¥èš±å¯ãããããšã«æ³šæããŠãã ããïŒ 2çªç®ã®æ¹æ³ã¯ããªã¹ãããŒã¿ã衚瀺ãããšããã³ã³ããã¹ããæ¢ã«ã³ã¬ã¯ã·ã§ã³ã®èŠçŽ ã§ãããšããã³ã³ãããŒã«ã®ç°ãªãããããã£ãç°ãªããœãŒã¹ã§
åäœããå¿
èŠãããå ŽåïŒ
ãã«ãã³ã³ããã¹ãã®
åäœ ïŒãªã©ãç¶æ³ã«ãã£ãŠéåžžã«åœ¹ç«ã¡ãŸãã
ProductsView㯠ãç°ãªããã¥ãŒã¢ãã«ã«é¢é£ä»ãããã2ã€ã®è«çéšåã§æ§æãããŠãããããæ³šæãã䟡å€ããããŸãã æåã®éšåã«ã¯ãŠãŒã¶ãŒã«é¢ããæ
å ±ãå«ãŸããŠããã
ãã°ã¢ãŠããå®è¡ã§ããŸãã2çªç®ã®éšåã«ã¯ããŠãŒã¶ãŒè£œåã®ãªã¹ããçŽæ¥è¡šç€ºãããŸãã ã»ãšãã©ã®å€å
žçãªå®è£
ã§ã¯ã
LoginViewModelã
ProductsViewModelã«æ³šå
¥ããå¿
èŠããããŸããããã®å Žåããã¥ãŒã¢ãã«ã¯äºãã«ããªãç¬ç«ããŠããããããœãªã¥ãŒã·ã§ã³ã¯ããçŸãããªããŸããã
ãã ãã
çŽæ¥æ³šå
¥ã®
åçã¯åºããªã£ãŠããŸãã ããšãã°ãBindable Dependancy ConvertersãçŸããå®è£
ããããšãã§ããŸããããã«ã€ããŠã¯ãåŸã§è©³ãã説æããŸãã
2ïŒ Exposableãã¿ãŒã³ãä»ããç¬ç«ããæ³šå
¥éèŠãªãã€ã³ãã¯ã
IExposableã€ã³ã¿ãŒãã§ã€ã¹ããã®ç¶æ¿ã§ã
ãIExposableã€ã³ã¿ãŒãã§ã€ã¹ã¯ããªããžã§ã¯ãã®é
å»¶åæåãæ
åœããŸãã ããã¯ãã€ã³ã¹ã¿ã³ã¹ãžã®åç
§ãåæååã§ã䜿çšå¯èœã«ãªãããšãæå³ããŸããããã¯ããªããžã§ã¯ããžã®ãã¹ãŠã®åç
§ã倱ãããã¬ããŒãžã³ã¬ã¯ã¿ãŒã«ãã£ãŠåé€ãããåã«ãªãœãŒã¹ãè§£æŸã§ãã
Disposableãã¿ãŒã³ïŒ
IDisposabeã€ã³ã¿ãŒãã§ã€ã¹ïŒã®äœ¿çšãšã¯æ£å察ã§ãã ãã®ãããªé
å»¶åæåã«ã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒã䜿çšããåŸæ¥ã®æ¹æ³ãããããã€ãã®å©ç¹ããããŸããã2çªç®ã®ãªãã·ã§ã³ã¯é€å€ãããŸãããããã«ãããšãã°ãã¡ã€ãã©ã€ã¶ãŒã§
Disposeã¡ãœãããåŒã³åºããªã©ãäžç·ã«äœ¿çšã§ããŸã
é
å»¶åæåã䜿çšãããšãçžäº
泚å
¥ãå«ãçžäºæ¥ç¶ããã2ã€ã®ãªããžã§ã¯ããåæåã§ãã
ç¬ç«æ³šå
¥ã®åçãå®è£
ã§ããŸãã
public class ProductsViewModel : ContextObject, IExposable { public virtual void Expose() { var settingsViewModel = Store.Get<SettingsViewModel>(); this[Context.Get("AnyCommand")].Executed += (sender, args) => {
public class SettingsViewModel : ContextObject, IExposable { public virtual void Expose() { var productsViewModel = Store.Get<SettingsViewModel>(); this[Context.Get("AnyCommand")].Executed += (sender, args) => {
Exposableãã¿ãŒã³ã®ä»£ããã«ã³ã³ã¹ãã©ã¯ã¿ãŒã䜿çšããå Žåããã¥ãŒã¢ãã«ã®1ã€ãäœæããããšãããšãååž°çãªã¹ã¿ãã¯ãªãŒããŒãããŒãçºçããŸãã ãã¡ãããåæåïŒ
Exposeã¡ãœããã®å®è¡ïŒã®ç¬éã«å¥ã®åæåãããŠããªããã¥ãŒã¢ãã«ã䜿çšããããšã¯æã
å®å
šã§ã¯ãªããšããå¶éãèŠããŠããå¿
èŠããããŸãããå®éã«ã¯ãã®ãããªç¶æ³ã¯ãŸãã§ãããã¯ã©ã¹èšèšã®èšèšã«ããããšã©ãŒã瀺ãå¯èœæ§ãæãé«ãã§ãã
ããã«ç¶æ¿ãèšç»ãããŠããå Žåã¯ã
Exposeã¡ãœããã
ä»®æ³ä¿®é£Ÿåãšãšãã«äœ¿çšããŠãç¶æ¿ãããã¯ã©ã¹ã§ãªãŒããŒã©ã€ããã倿
çãªåäœãæäŸã§ããããã«ããå¿
èŠããããŸãã
3ïŒ ã³ãã³ãæåããã²ãŒã·ã§ã³ããããããã¯ããªãè峿·±ãåŽé¢ã§ãã ç°ãªããã©ãããã©ãŒã ãªã©ãè€æ°ã®ãããžã§ã¯ãã§ãã¥ãŒã¢ãã«ã®åãããžãã¹ããžãã¯ãåå©çšããå¯èœæ§ãæäŸããã«ã¯ããããã®
UIã¯ã©ã¹ãžã®åç
§ãåé€ããå¿
èŠããããŸãã ããããç¹å®ã®ããžãã¹ã«ãŒã«ã®å®è£
ã«å¿ããŠããã¬ãŒã³ããŒã·ã§ã³ãéžæããã¡ã«ããºã ãã©ã®ããã«ç·šæããã®ã§ããããïŒ
CM-ãã¿ãŒã³ã¯ããã®ããã®æšå¥šäºé
ãæäŸã
ãŸã -
ã³ãã³ãã¡ã«ããºã ã䜿çšãã衚çŸã®ã¿ã€ããŸãã¯uriãã³ãã³ãã«ãã©ã¡ãŒã¿ãŒãšããŠæž¡ãå¿
èŠããããŸã ã
<Button Content="{Localizing GoToPayment}" Command="{Context Key=GoTo}" CommandParameter="{x:Type PaymentView}">
<Button Content="{Localizing GoToPayment}" Command="{Context Key=GoTo}" CommandParameter="/Views/PaymentView.xaml">
public class AnyViewModel : ContextObject, IExposable { public virtual void Expose() {
Navigatorã¯ã©ã¹ã¯ãã®ãã©ã¡ãŒã¿ãŒãåãåããããã«åºã¥ããŠç®çã®ãã¥ãŒã«ç§»åããŸãã çŽæ¥æ³šå
¥ã¡ã«ããºã ã䜿çšãããšã次ã®è¡šçŸã¯å¿
èŠãªã³ã³ããã¹ããªããžã§ã¯ãïŒãã¥ãŒã¢ãã«ïŒã«ç°¡åã«é¢é£ä»ããããŸãããããã£ãŠãã©ã®è¡šçŸãã³ã³ããã¹ããªããžã§ã¯ãã«ã¢ã¯ã»ã¹ã§ãããããããã²ãŒã·ã§ã³äžã«ãµãŒãã¹ãã©ã¡ãŒã¿ãçŽæ¥è»¢éããå¿
èŠããªããªããŸãã ç¹å®ã®ç»é¢ã«åãæ¿ããæ©èœã¯ãããŒã ã®
CanExecuteã€ãã³ãã«ãã£ãŠèŠå¶ãããŠããŸãã
ãã¹ãŠãéåžžã«ãšã¬ã¬ã³ãã§ã·ã³ãã«ã«ãªããŸããã ãã ããã³ãã³ããã©ã¡ãŒã¿ãååŸãããããä»ã®ããŒã¿ãéä¿¡ããããšã¯ã§ããŸããã ããããçŸãã解決çããããŸããéåžžã«ããªããã£ããª
Setã¯ã©ã¹ã䜿çšããŸãã
public class Set : List<object> { }
ããã«ãããããŸããŸãªèŠçŽ ã®ã³ã¬ã¯ã·ã§ã³ã
xamlã§çŽæ¥äœæã§ããŸãã ããšãã°ããªãœãŒã¹ã«ãã©ãŒã ã®ã¬ã³ãŒããé
眮ããããšã«ããïŒ
<Set x:Key="ParameterSet"> <system:String>/Views/AnyView.xaml</system:String> <system:String>SecondParaneter</system:String> </Set>
ã³ãã³ãã«ããã€ãã®åŒæ°ãç°¡åã«æž¡ãããšãã§ããŸãã
<Button Content="{Localizing GoToAnyView}" Command="{Context Key=GoTo}" CommandParameter="{StaticResource ParameterSet}">
4ïŒåçãªããŒã«ãªãŒãŒã·ã§ã³ããŒã«ãªãŒãŒã·ã§ã³ã¯ããã€ã³ãã£ã³ã°/ããŒã¯ã¢ããæ¡åŒµæ©èœã䜿çšããŠå®è£
ãããŸããããã«ãããã¢ããªã±ãŒã·ã§ã³ã®å®è¡äžã«ãããèšèªã®å€æŽãå®è£
ã§ããŸãã ã€ãŸããããŒã«ã©ã€ãºãããæååã®ãœãŒã¹ã¯ãããŒã«ãã£ãŠå¿
èŠãªå€ãæœåºãããæ³šå
¥ãããã³ã³ããã¹ããªããžã§ã¯ãã§ãã
Windowsãã¹ã¯ãããã®å Žåãéåžžã«åçŽãªæ§æãåãå
¥ããããŸãã
Text="{Localizing Name}" Text="{Localizing Key=Name}"
Windows Phoneã¯ããå°ãè€éã§ãããéåžžã«åºæ¬çãªãã®ã§ããããŸãã
Text="{m:Localizing Key=Name}"
CïŒã³ãŒãã§ã¯ãé©åãªã¿ã€ãã³ã°ã§ãªãœãŒã¹ãããŒãžã£ãŒãã€ã³ã¹ããŒã«ããå¿
èŠããããŸãïŒã¢ããªã±ãŒã·ã§ã³ã®ããŒãæãŸãã¯èšèªã®å€æŽæïŒã
Localizing.DefaultManager.Source = English.ResourceManager;
ãããŠã次ã®ãããªããŒã«ã©ã€ãºãããæååãååŸã§ããŸãã
var localizedValue = Unity.App.Localize("KeyValue");
5ïŒ ã³ã³ããã¹ãã³ãã³ããšããªã¬ãŒå€å
žçãª
ãã¹ã¯ãããWPFã§ã¯ã匷åã§äŸ¿å©ãª
Routed Commandsã®æŠå¿µã詳现
ã«éçºãããŸããããæè¡çãªéããªã©ã«ããä»ã®ãã©ãããã©ãŒã ã§ã¯ãµããŒããããŠããªããããæ®éçãæ§æçãã€ããªãã®ãŒçã«é¡äŒŒããäœããäœæã§ãããã©ãããšããçåãçããŸããåæã«ã«ãŒãã£ã³ã°å¯èœãªã³ãã³ããšäºææ§ããããŸãã
ãã®çµæã
ã³ã³ããã¹ãã³ãã³ãã®ã¢ã€ãã¢ãçãŸããŸããã äžèšã®ããã«ãéåžžã«äœ¿ãããããããã«ã
Routed Commandsãšå®å
šã«äºææ§ããããŸãã
<Button Content="{Localizing GoToPayment}" Command="{Context Key=GoTo}" CommandParameter="/Views/PaymentView.xaml"/>
<Button Content="{Localizing New}" Command="New"/>
public class AnyViewModel : ContextObject, IExposable { public virtual void Expose() {
éç
Contextã¯ã©ã¹ã«ã¯ã以åã«å®£èšãããããã€ãã®ã³ãã³ãåãå«ãŸããŠãããå¿
èŠã«å¿ããŠç¬èªã®ã³ãã³ãåã远å ã§ããŸãã
ãã®[Context.Make] ãšãã®[Context.GetïŒ "Make"ïŒ]ã®ãšã³ããª
ã¯äºãã«åçã§ãã ã³ã³ããã¹ãã³ãã³ãã®å®è£
ã¯ãã¡ã¢ãªãªãŒã¯ã«é¢ããŠå®å
šã§ããããšã«æ³šæããŠãã ãããç¶æ³ã«ãã£ãŠã¯ãã³ãã³ãã®
CanExecuteChangedã€ãã³ã
ã«å¶åŸ¡ããµãã¹ã¯ã©ã€ããããšãã¬ããŒãžã³ã¬ã¯ã·ã§ã³ããã€ã³ã¿ãŒãã§ã€ã¹ãææ¢ãããå¯èœæ§ããããŸãã
ã³ã³ããã¹ãã³ãã³ãã¯ãããžã¥ã¢ã«ããªãŒãä»ããŠã«ãŒãã£ã³ã°ãããŸãã
ã ãããžã¥ã¢ã«èŠçŽ èªäœãŸãã¯ãã®ç¥å
ã®
DataContextããããã£ã§èšå®ãããŠããæãè¿ãã³ã³ããã¹ããªããžã§ã¯ãã§å®è¡ãããŸãã ãã ããçŽæ¥æ³šå
¥ã®ååã«ããã°ãã³ã³ããã¹ããªããžã§ã¯ãã¯ããŒã ã¡ãã£ãšãŒã¿ãŒèªäœã«çŽæ¥ã€ã³ã¹ããŒã«ã§ãããããæè»æ§ãšæ±çšæ§ã«åªããŠããŸãã
<Button DataContext="{Store viewModels:FirstViewModel}" Command="{Context Key=Make}">
<Button DataContext="{Store viewModels:FirstViewModel}" IsEnabled="{Binding CanMake}" Command="{Context Key=Make, StoreKey=viewModels:SecondViewModel}">
æåã®å ŽåãMakeã³ãã³ãã¯
FirstViewModelã«ãã£ãŠå®è¡ããã2çªç®ã®å Žåã¯
SecondViewModelã«ãã£ãŠå®è¡ãããŸãã
ãŸããã³ãã³ãã®ã³ã³ããã¹ãããªã¬ãŒã«èšåããå¿
èŠããããŸãã å€ãã®å Žåãç¹å®ã®å¶åŸ¡ã€ãã³ããçºçãããšãããšãã°ããŒãžã®èªã¿èŸŒã¿æã«ããžãã¹ããŒã¿ãèŠæ±ãŸãã¯æŽæ°ããå¿
èŠãããå Žåãããã€ãã®ã¢ã¯ã·ã§ã³ãŸãã¯äžé£ã®ã¢ã¯ã·ã§ã³ãå®è¡ããå¿
èŠããããŸãã ãã®æ©èœã¯ã³ãã³ãããªã¬ãŒã䜿çšããŠå®è£
ããã
ã«ãŒãã£ã³ã°ã€ãã³ãã ãã§ãªãããã¹ãŠã®ã¿ã€ãã®ã€ãã³ãããµããŒããããŸãã
<Window> <Attacher.ContextTriggers> <Set> <ContextTrigger EventName="Loaded" Command="{Context Refresh, StoreKey=viewModels:AppViewModel}"/> <ContextTrigger EventName="Closing" UseEventArgsAsCommandParameter="True" Command="{Context Exit, StoreKey=viewModels:AppViewModel}"/> </Set> </Attacher.ContextTriggers> ... </Window>
ãã®äŸã§ã¯ãããªã¬ãŒã¯ããžã¥ã¢ã«ããªãŒã®ç¶æ¿ã§ã¯ãªããšããäºå®ã«æ³šæããããšãéèŠã§ãããã®ãããã³ã³ããã¹ããªããžã§ã¯ãã¯ã³ãã³ãmediator-
StoreKey = viewModelsïŒAppViewModelã«çŽæ¥æ³šå
¥ããå¿
èŠããããŸãã ã³ãã³ãã«ãã©ã¡ãŒã¿ãŒãšããŠã€ãã³ãåŒæ°ãæž¡ãããšãã§ããŸãã ãããã£ãŠããŠã£ã³ããŠãéãããšãã
Closingã€ãã³ãã¯ã
args.Cancel = trueãèšå®ãã
ããšã«ããã¢ã¯ã·ã§ã³ã
åãæ¶ãå¯èœæ§ããã
ãŸã ã
6ïŒ ããããã£ã®éç¥ãšæ€èšŒã€ã³ã¿ãŒãã§ã€ã¹ããã³ä»ã®ããã°ã©ã ãªããžã§ã¯ãã«ããããã£ã®å€æŽã«ã€ããŠéç¥ããããã«ãINotifyPropertyChangedã€ã³ã¿ãŒãã§ã€ã¹ããããŸãã Aeroãã¬ãŒã ã¯ãŒã¯ã¯ããã®ãããªç®çã®ããã®äŸ¿å©ãªã¡ã«ããºã ã倿°æäŸããŸãã ãŸããContextObjectã¯ã©ã¹ããç¶æ¿ããå¿
èŠããããŸãããã®åŸãç°¡æœã§äŸ¿å©ãªæ§æã䜿çšã§ããããã«ãªããŸãã
public class LoginViewModel : ContextObject, IExposable {
ããããã£ã宣èšããæåã®æ¹æ³ã§ã¯ãä»ã®ãªããžã§ã¯ãã«å€æŽãèªåçã«éç¥ã§ããŸãããæ¬¡ã®ãããªå€æ
çãªã¡ãœãã
RaisePropertyChangingããã³
RaisePropertyChangedã䜿çšããŠããã®ãããªéç¥ãæåã§è¡ãããšãã§ããŸãã
RaisePropertyChanging(() => Password); RaisePropertyChanged(() => Password);
RaisePropertyChanging("Name"); RaisePropertyChanged("Name");
this [ïŒïŒ=> Name] .PropertyChangedãšãã衚èšã¯ãé¢åãª
if-elseæ§é ãåé¿ããããã«ãå€éšããããããã£ã倿Žããããã«ç°¡åã«ãµãã¹ã¯ã©ã€ãããŸãã
var loginViewModel = Store.Get<LoginViewModel>(); loginViewModel[() => Name].PropertyChanging += (sender, args) => {
ã€ãã³ãã«ãµãã¹ã¯ã©ã€ããããšããµãŒãããŒãã£ã®ãªã¹ãã³ã°ãªããžã§ã¯ããã¬ããŒãžã³ã¬ã¯ã·ã§ã³ããä¿æããããããã€ãã³ãããæéã©ããã«ãµãã¹ã¯ã©ã€ããè§£é€ãããã匱ããµãã¹ã¯ãªãã·ã§ã³ã¡ã«ããºã ã䜿çšããŠãç¶æ³ã«ãã£ãŠã¯ã¡ã¢ãªãªãŒã¯ãåé¿ããå¿
èŠããããŸãã
ããããã£å€ã®æ€èšŒãããã®ã¢ãããŒãã䜿çšããŠ
IDataErrorInfoã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ãããšäŸ¿å©ã§ãã
this[() => Name].Validation += (sender, args) => Error = Name == null || Name.Length < 3 ? Unity.App.Localize("InvalidName") : null; this[() => FontSize].Validation += () => 4.0 < FontSize && FontSize < 128.0 ? null : Unity.App.Localize("InvalidFontSize");
7ïŒãã¹ããŒããç¶æ
ïŒ ã¹ããŒãç¶æ
ïŒä»ãéåžžã«çããã§ãããåæã«ç¶æ
ãç¶æããããã®äŸ¿å©ãªã¡ã«ããºã ã«ãªããŸãã
Aeroãã¬ãŒã ã¯ãŒã¯ã䜿çšãããšããã®çš®ã®åé¡ã解決ããããã«ãéåžžã«ãšã¬ã¬ã³ãã§åè¶ããç°¡æœãªåããå®çŸã§ããŸãã
æåã«ãäŸã®ãã¥ãŒã¢ãã«ã¯
DataContract屿§ã§ããŒã¯ãããäžéšã®ããããã£ã¯
DataMember屿§ã§ããŒã¯ãããŠããããšããã
ãŸã ãããã«ãããã·ãªã¢ã«åããã³éã·ãªã¢ã«åã¡ã«ããºã ã䜿çšããŠè«çç¶æ
ãä¿åããã³åŸ©å
ã§ããŸãã
ãã®ããã«å¿
èŠãªããšã¯ãã¢ããªã±ãŒã·ã§ã³ã®èµ·åæã«å¿
èŠã«å¿ããŠãã¬ãŒã ã¯ãŒã¯ãåæåããããšã ãã§ãã Unity.AppStorage = new AppStorage(); Unity.App = new AppAssistent();
ããã©ã«ãã§ã¯ãã·ãªã¢ã«åã¯ãã¡ã€ã«ã§è¡ãããŸãããç¬èªã®å®è£
ãç°¡åã«äœæããã·ãªã¢ã«åããããªããžã§ã¯ããããŒã¿ããŒã¹ãªã©ã«ä¿åã§ããŸãããããè¡ãã«ã¯ãUnity.IApplicationã€ã³ã¿ãŒãã§ã€ã¹ããç¶æ¿ããå¿
èŠããããŸãïŒAppStorageã¯ããã©ã«ãã§å®è£
ãããŠããŸãïŒãUnity.IApplicationïŒAppAssistentïŒã€ã³ã¿ãŒãã§ãŒã¹ã«ã€ããŠã¯ãã·ãªã¢ã«åäžã®æåçèšå®ã«å¿
èŠã§ãããã»ãšãã©ã®å Žåãæšæºå®è£
ã«å¶éã§ããŸããã·ãªã¢ã«åããµããŒããããªããžã§ã¯ãã®ç¶æ
ãä¿åããã«ã¯ãæ·»ä»ã®Snapshotã¡ãœãããåŒã³åºããããªããžã§ã¯ããå
±éã³ã³ãããŒã«ããå Žåã¯Store.SnapshotåŒã³åºãã䜿çšããŸããè«ççãªç¶æ
ãç¶æããããšãèãåºããŸããããå€ãã®å ŽåããŠã£ã³ããŠã®ãµã€ãºãšäœçœ®ãã³ã³ãããŒã«ã®ç¶æ
ããã®ä»ã®ãã©ã¡ãŒã¿ãŒãªã©ãã¹ãã¬ãŒãžãšããžã¥ã¢ã«ãå¿
èŠã§ããCM-ãã¿ãŒã³ã¯ãéæšæºã§ããéåžžã«äŸ¿å©ãªãœãªã¥ãŒã·ã§ã³ãæäŸããŸãããã®ãããªãã©ã¡ãŒã¿ãŒãã³ã³ããã¹ããªããžã§ã¯ãïŒãã¥ãŒã¢ãã«ïŒã«æ ŒçŽããã·ãªã¢ã«åã®ããã®åå¥ã®ããããã£ãšããŠã§ã¯ãªããæé»çã«ãããŒããä»®æ³ãããããã£ã®ååã§ããèŸæžãšããŠæ ŒçŽãããšã©ããªããŸããïŒãã®æŠå¿µã«åºã¥ããŠãã¹ããŒãããããã£ã®ã¢ã€ãã¢ãçãŸããŸãããã¹ããŒãããããã£ã®å€ã¯ããã£ã¯ã·ã§ããªã®ããã«ãããŒåã§ã€ã³ãã¯ãµãŒãä»ããŠã¢ã¯ã»ã¹ã§ããå¿
èŠããããŸããã¯ã©ã·ãã¯getãŸãã¯setã¯ãªãã·ã§ã³ã§ãããååšããªãå ŽåããããŸãããã®æ©èœã¯SmartObjectã¯ã©ã¹ã«å®è£
ãããŠããŸãããContextObjectã®ç¶æ¿å
ã§ãããå±éããŸãããã¹ã¯ãããçã§æžãã ãã§ãïŒ public class AppViewModel : SmartObject
<Window x:Class="Sparrow.Views.AppView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:viewModels="clr-namespace:Sparrow.ViewModels" DataContext="{Store Key=viewModels:AppViewModel}" WindowStyle="{ViewModel DefaultValue=SingleBorderWindow}" ResizeMode="{Binding '[ResizeMode, CanResizeWithGrip]', Mode=TwoWay}" Height="{Binding '[Height, 600]', Mode=TwoWay}" Width="{ViewModel DefaultValue=800}" Left="{ViewModel DefaultValue=NaN}" Top="{Binding '[Top, NaN]', Mode=TwoWay}" Title="{ViewModel DefaultValue='Sparrow'}" Icon="/Sparrow.png" ShowActivated="True" Name="This"/>
! , . - - .
Window Phone , -, ,
smart - , ,
Indexer ViewModel . , :
Background="{m:ViewModel Index=UseTable, FinalConverter={StaticResource BackgroundConverter}, Mode=OneWay, StoreKey=viewModels:SettingsViewModel, DefaultValue=True}"
SelectedIndex="{m:ViewModel Index=SelectedIndex, StoreKey=viewModels:AppViewModel}"
,
Indexer , , , . - , , .
Aero Framework «» . , ,
SelectedIndex .
<TabControl Grid.Row="2" Name="TabControl" MouseMove="UIElement_OnMouseMove" ItemsSource="{Binding Documents}" SelectedItem="{Binding Document}" SelectedIndex="{Binding '[DocumentIndex, 0, True].Value', Mode=TwoWay}">
SelectedIndex="{Binding '[DocumentIndex, 0]', Mode=TwoWay}"
ãã¹ãã¢ããªã±ãŒã·ã§ã³ã®ãã¹ãŠã®ã¿ããéããŠãVisual Studioã§ãããã°ã¢ãŒãã§ã¡ã€ã³ãŠã£ã³ããŠãç§»åãããšãVisual Studioã®ãåºåãã§ãã¬ãŒã¹ããã€ã³ããã¯ã¹ããããã£ã®æŽæ°ããšã«TabControlãäŸå€ãçæãããããã¹ããŒããŠã³ãçºçããŸãããã®ãããªç¶æ³ã¯ãŸãã§ãããã«ãŒã«ã®äŸå€ã§ããå¯èœæ§ãé«ããªããŸãããåé¢ã䜿çšãããšç°¡åã«åé¡ã解決ã§ããŸããããªã¢ãŒãã£ãºã ã¡ã«ããºã ã®ãããã§ãã€ã³ãã¯ãµãŒã䜿çšããIDataErrorInfoã€ã³ã¿ãŒãã§ã€ã¹ã®å®è£
ã«ããããããã£å€ã®æ€èšŒã¯ãã¹ããŒãã¹ããŒãã®æŠå¿µã«éåžžã«ãšã¬ã¬ã³ãã«é©åããŸãããŸãšãäžèšã®æ
å ±ã¯ãã§ã«ãAero Frameworkã©ã€ãã©ãªã䜿çšããŠCMãã¿ãŒã³ã«å¯Ÿå¿ããã¢ããªã±ãŒã·ã§ã³ã®ããã°ã©ãã³ã°ãéå§ããã®ã«ååã§ããä»ã«äœãç¥ãå¿
èŠããããŸããïŒãŸããããŸããŸãªã·ãªã¢ã©ã€ã¶ãŒã®åäœã®ãã¥ã¢ã³ã¹ãææ¡ããŠãããšäŸ¿å©ã§ããAeroãã¬ãŒã ã¯ãŒã¯ã¯ããã©ã«ãã§DataContractJsonSerializerã䜿çšããŸãããå¿
èŠã«å¿ããŠå¥ã®ãã®ã䜿çšã§ããŸãããã®ã³ã³ãã©ã¯ãã·ãªã¢ã©ã€ã¶ãŒã¯ããªããžã§ã¯ããéã·ãªã¢ã«åãããšãã«ã³ã³ã¹ãã©ã¯ã¿ãŒãåŒã³åºãããæ¢å®ã®ãã£ãŒã«ããåæåããªãããšãèŠããŠããããšãéèŠã§ãïŒ
ãŸããKnownTypesã³ã¬ã¯ã·ã§ã³ã®ã·ãªã¢ã©ã€ã¶ãŒã«ãªãã¿ã®ãªãåã远å ããå¿
èŠãããå ŽåããããŸãã ContractFactory.KnownTypes.Add(typeof(SolidColorBrush));
â¢æ¡åŒµæ©èœã®ãã€ã³ã xaml-ãã©ãããã©ãŒã ã®äžéšã®å®è£
ã§ã¯ãåãååã®ã¯ã©ã¹ããç¶æ¿ããããšã«ãããç¬èªã®ããŒã¯ã¢ããæ¡åŒµæ©èœãäœæã§ããŸãããããããã®ãããªæ©äŒã¯ã©ãã«ãååšããŸãããããã§ããã»ãšãã©ã®å ŽåãBindingã¯ã©ã¹ããã®ç¶æ¿ã¯èš±å¯ãããŠããŸãã using System; using System.Globalization; using System.Windows.Data; namespace Aero.Markup.Base { public abstract class BindingExtension : Binding, IValueConverter { protected BindingExtension() { Source = Converter = this; } protected BindingExtension(object source)
MarkupExtension , , Binding, .
⢠Bindable Dependency Converters,
xaml , , , - .
IValueConverter DependencyObject DependencyPropertyãã³ã³ããŒã¿ã¯ããžã¥ã¢ã«ããªãŒã®èŠçŽ ã§ã¯ãªããããã»ãšãã©ã®å Žåããã€ã³ãã£ã³ã°ã¯æ©èœããŸããïŒãã¡ãããããã«é²ãã§ãã€ããªããã³ã³ãããŒã©ãŒã³ã³ããŒã¿ãŒãäœæããããšãã§ããŸããããã®ãããªãšããŸããã¯ãªãœãªã¥ãŒã·ã§ã³ã¯çŸãããšã¯èšããããã®é©çšç¯å²ã¯éãããŠããŸããããããåè¿°ã®ããã«ãçŽæ¥æ³šå
¥ã®ååã¯ãStoreBindingãDependency Converterã«é©çšããããšã劚ãããã®ã§ã¯ãªããããæãã«ãªããŸãã <BooleanConverter x:Key="BindableConverter" OnTrue="Value1" OnFalse="Value2" OnNull="{StoreBinding StoreKey=viewModels: SettingsViewModel, Path=AnyValue3Path}"/>
Switch Converterå€§èŠæš¡ãªãããžã§ã¯ãã§ã¯ãå€ãã®å Žåãswitchæã®åäœã«éåžžã«é¡äŒŒããããžãã¯ãæã€åãã¿ã€ãã®å€ãã®ç°ãªãã¿ã€ãã®ã³ã³ããŒã¿ãŒã¯ã©ã¹ãäœæããå¿
èŠããããŸãããããå®éã«ã¯ãå€ãã®å ŽåããŠãããŒãµã«ã¹ã€ããã³ã³ããŒã¿ãŒã®äœ¿çšã«å¶éããããšãã§ããŸãã <SwitchConverter Default="ResultValue0" x:Key="ValueConverter1"> <Case Key="KeyValue1" Value="ResultValue1"/> <Case Key="KeyValue2" Value="ResultValue2"/> </SwitchConverter>
ããã«ããã®ã³ã³ããŒã¿ãŒã®ããããã£ïŒCaseæ§é ãå«ãïŒã¯Dependencyã§ããã€ãŸããStoreBindingã䜿çšãããã€ã³ãã£ã³ã°ã«äœ¿çšã§ããŸããããã«ãããŒããªããžã§ã¯ãèªäœã®å€ã§ã¯ãªããã¿ã€ãã§ããå Žåãã¿ã€ãã¢ãŒãããµããŒããããŸãã <SwitchConverter TypeMode="True" Default="{StaticResource DefaultDataTemplate}" x:Key="InfoConverter"> <Case Type="local:Person" Value="{StaticResource PersonDataTemplate}"/> <Case Type="local:PersonGroup" Value="{StaticResource PersonGroupDataTemplate}"/> </SwitchConverter>
ãã®ãããªã³ã³ããŒã¿ãŒã¯ãåŸè
ããµããŒããããŠããªãå Žåã§ããDataTemplateSelectorãšããŠç°¡åã«é©çšã§ããããšãããããŸããïŒSwitchConverterã®æ±çšæ§ã«ãããèšå€§ãªæ°ã®ã±ãŒã¹ãã«ããŒã§ããŸããå°ãæ³ååããããã°ããã ãã§ããâ¢ã°ããŒãã«ãªãœãŒã¹ïŒã³ã³ããŒã¿ãŒã«ã€ããŠè©±ãå§ããã®ã§ãã³ã³ããŒã¿ãŒã§äœæ¥ãæŽçããæé©ãªæ¹æ³ã説æããããšã¯äŸ¡å€ããããŸãããŸããæãäžè¬çãªãã®ãå¥ã®ãªãœãŒã¹ãã£ã¯ã·ã§ããªã«é
眮ããå¿
èŠããããŸãã <!--AppConverters .xaml--> <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <BooleanConverter x:Key="NullToTrueConverter" OnNull="True" OnNotNull="False"/> <BooleanConverter x:Key="NullToFalseConverter" OnNull="False" OnNotNull="True"/> <BooleanConverter x:Key="NullToVisibleConverter" OnNull="Visible" OnNotNull="Collapsed"/> <BooleanConverter x:Key="NullToCollapsedConverter" OnNull="Collapsed" OnNotNull="Visible"/> <BooleanConverter x:Key="TrueToFalseConverter" OnTrue="False" OnFalse="True" OnNull="True"/> <BooleanConverter x:Key="FalseToTrueConverter" OnTrue="False" OnFalse="True" OnNull="False"/> <BooleanConverter x:Key="TrueToVisibleConverter" OnTrue="Visible" OnFalse="Collapsed" OnNull="Collapsed"/> <BooleanConverter x:Key="TrueToCollapsedConverter" OnTrue="Collapsed" OnFalse="Visible" OnNull="Visible"/> <BooleanConverter x:Key="FalseToVisibleConverter" OnTrue="Collapsed" OnFalse="Visible" OnNull="Collapsed"/> <BooleanConverter x:Key="FalseToCollapsedConverter" OnTrue="Visible" OnFalse="Collapsed" OnNull="Visible"/> <EqualsConverter x:Key="EqualsToCollapsedConverter" OnEqual="Collapsed" OnNotEqual="Visible"/> <EqualsConverter x:Key="EqualsToVisibleConverter" OnEqual="Visible" OnNotEqual="Collapsed"/> <EqualsConverter x:Key="EqualsToFalseConverter" OnEqual="False" OnNotEqual="True"/> <EqualsConverter x:Key="EqualsToTrueConverter" OnEqual="True" OnNotEqual="False"/> <AnyConverter x:Key="AnyToCollapsedConverter" OnAny="Collapsed" OnNotAny="Vsible"/> <AnyConverter x:Key="AnyToVisibleConverter" OnAny="Visible" OnNotAny="Collapsed"/> <AnyConverter x:Key="AnyToFalseConverter" OnAny="False" OnNotAny="True"/> <AnyConverter x:Key="AnyToTrueConverter" OnAny="True" OnNotAny="False"/> </ResourceDictionary>
次ã«ããã®èŸæžãApp.xamlã®ãªãœãŒã¹ã«çŽæ¥ãŸãã¯éæ¥çã«å«ããå¿
èŠããããŸããããã«ããã远å ã®æé ãè¡ããªããŠããã¢ããªã±ãŒã·ã§ã³ã®ã»ãŒãã¹ãŠã®xaml-ãã¡ã€ã«ã§ã¡ã€ã³ã³ã³ããŒã¿ãŒã䜿çšã§ããŸããã¢ããªã±ãŒã·ã§ã³ã®ã°ããŒãã«ãªãœãŒã¹ãžã®ãã®ãããªè¿œå ã¯ãå€ããå°ãªããäžè¬çãªãã®ã«åœ¹ç«ã¡ãŸããè²ããã©ã·ããã¿ãŒã³ãã¹ã¿ã€ã«-ããšãã°ãã¢ããªã±ãŒã·ã§ã³ã®ããŒãã倿Žããã¡ã«ããºã ãéåžžã«ç°¡åã«å®è£
ããã®ã«åœ¹ç«ã¡ãŸãã <Application x:Class="Sparrow.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="Views/AppView.xaml"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <!--<ResourceDictionary Source="AppConverters.xaml"/>--> <ResourceDictionary Source="AppStore.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application>
â¢ã»ããåè¿°ã®ããã«ãå€ãã®å Žåã«é©çšã§ããxamlã®ãŠãããŒãµã«ã³ã¬ã¯ã·ã§ã³ã»ããã䜿çšãããšäŸ¿å©ãªå ŽåããããŸããå Žåã«ãã£ãŠã¯ããå€éæ§é ããé¿ããäžè¬çãªãã€ã³ããäœæããã³ãŒããããæ£ç¢ºã«ããããšãã§ããŸãã <Set x:Key="EditMenuSet" x:Shared="False"> <MenuItem Header="{Localizing Undo}" Command="Undo"/> <MenuItem Header="{Localizing Redo}" Command="Redo"/> <Separator/> <MenuItem Header="{Localizing Cut}" Command="Cut"/> <MenuItem Header="{Localizing Copy}" Command="Copy"/> <MenuItem Header="{Localizing Paste}" Command="Paste"/> <MenuItem Header="{Localizing Delete}" Command="Delete"/> <Separator/> <MenuItem Header="{Localizing SelectAll}" Command="SelectAll"/> </Set> <MenuItem Header="{Localizing Edit}" ItemsSource="{StaticResource EditMenuSet}"/>
ããã ãã§ããïŒããã§ã¯ãããŸãã...äž»ãªã³ã³ããŒãã³ãã¯éçºè
ã®ãã¡ã³ã¿ãžãŒã§ãããããéçºããŸããæ¢çŽ¢ãå®éšãæ§ç¯ïŒPSã€ã³ããã¯ã¹ããããã£ã®æŠå¿µã«ã¯ã屿§ã®ãªã飿³ããŒã¿ã¢ãã«ãšå
±éç¹ããããããååãªåŒ·åºŠãšå¥œå¥å¿ãããå Žåã¯ããæèããšããèšäºãèªãã®ãçã«ããªã£ãŠããŸãã