ã¿ãªããããã«ã¡ã¯ïŒ
ããŸããŸãªçç±ã§ãç§ãã¡ã®ã»ãšãã©ã¯ãã¹ã¯ãããã¢ããªã±ãŒã·ã§ã³ãå°ãªããšããã©ãŠã¶ã䜿çšããŠããŸã:)ãããŠãç§ãã¡ã®äœäººãã¯èªåã§æžãå¿ èŠããããŸãã ãã®èšäºã§ã¯ã Windows Presentation FoundationïŒWPFïŒãã¯ãããžãŒã䜿çšããMVVMãã¿ãŒã³ãé©çšããåçŽãªãã¹ã¯ãããã¢ããªã±ãŒã·ã§ã³ã®éçºããã»ã¹ã«ã€ããŠèª¬æããŸã ã ç«ã®äžã§ãèªã¿ç¶ããã人ã
WPFã¯Microsoftã®éçºã§ãããšèšãå¿ èŠã¯ãªããšæããŸã:)ãã®ãã¯ãããžãŒã¯ãWindows XPããWindowsçšã®ãã¹ã¯ãããã¢ããªã±ãŒã·ã§ã³ãéçºããããã«èšèšãããŠããŸãã ãªãããã§ããïŒ ããã¯ãWPFã.NETãã©ãããã©ãŒã äžã§å®è¡ãããããã§ãããã®æå°èŠä»¶ã¯Windows XP以éã§ãã æ®å¿µãªãããWPFã¯ä»ã®ãã©ãããã©ãŒã ã§ã¯åäœããŸããããè¿ãå°æ¥ã«å€æŽãããå¯èœæ§ããããŸããWPFããŒã¹ã®Avaloniaãã¬ãŒã ã¯ãŒã¯ã¯éçºäžã§ãã
WPFã®ç¹å¥ãªç¹ã¯äœã§ããïŒ
WPFãšä»ã®ãã¹ã¯ãããæ§ç¯ããŒã«ã®2ã€ã®äž»ãªéãïŒ
- ãŠã£ã³ããŠã€ã³ã¿ãŒãã§ã€ã¹èªäœãããŒã¯ã¢ããããããã®XAMLããŒã¯ã¢ããèšèªã
- ããŒããŠã§ã¢ã¢ã¯ã»ã©ã¬ãŒã·ã§ã³ã°ã©ãã£ãã¯ã¹ã§ããDirectXã«ããã¬ã³ããªã³ã°ã
詳现ã¯èª¬æããŸããããªããªã ããã¯èšäºã®ãããã¯ã§ã¯ãããŸããã èå³ãããå Žåã¯ãGoogle XAMLãWPFã¬ã³ããªã³ã°ãmilcore.dllãDirectX :)
ãã®èšäºã¯äœã«ã€ããŠã§ããïŒ
ãã®èšäºã«ã¯ãWPFãã¯ãããžãŒäžã«æ§ç¯ããããµã³ãã«ã¢ããªã±ãŒã·ã§ã³ãå«ãŸããŠããŸãã
ç§ã¯ã説æã®ãããç§ã®ããšãç¹°ãè¿ããã¹ã¿ã€ã«ã§ãèšäºã®å 容ãå®çšçãªæ¹åã«åããããšããŸãã
èšäºãç¹°ãè¿ãã«ã¯äœãå¿ èŠã§ããïŒ
CïŒã§ã®éçºçµéšã¯ã»ãšãã©ãããŸãã:)å°ãªããšããèšèªæ§æãããç解ããå¿ èŠããããŸãã Visual Studioãã€ã³ã¹ããŒã«ãããWindowsãã·ã³ïŒäŸã§ã¯Win 10ïŒãå¿ èŠã«ãªããŸãïŒäŸã§ã¯2017幎ã«ãªããç¡æã®ã³ãã¥ããã£ããŒãžã§ã³ããããŸãïŒã VSãã€ã³ã¹ããŒã«ããå Žåã.NETãã©ãããã©ãŒã ã®ãã¹ã¯ãããéçºã®ãµããŒããæå¹ã«ããå¿ èŠããããŸãã
ãŸãããã®ã»ã¯ã·ã§ã³ã§ã¯ããããžã§ã¯ãã®äœæã«ã€ããŠèª¬æããŸãã
VSãèµ·åããæ°ãããããžã§ã¯ããäœæããã¢ããªã±ãŒã·ã§ã³ã¿ã€ãWPF AppïŒ.NET FrameworkïŒãéžæãïŒå³äžã®æ€çŽ¢ããŒã«å ¥åã§ããŸãïŒã奜ããªååã§åŒã³åºããŸãã
æ°ãããããžã§ã¯ããäœæãããšãã€ã³ã¿ãŒãã§ã€ã¹ãšãã£ã¿ãŒãŠã£ã³ããŠãéããŸãã
äžéšã«ã¯ã¬ã€ã¢ãŠããšãã£ã¿ãŒããããäžéšã«ã¯ãŠã£ã³ããŠã€ã³ã¿ãŒãã§ã€ã¹ã®ãã¬ãã¥ãŒããããŸãããã³ãŒããšãã£ã¿ãŒãšã€ã³ã¿ãŒãã§ã€ã¹ãã¬ãã¥ãŒã®çžå¯Ÿçãªäœçœ®ãå€æŽããŠããããã®ãã¿ã³ã䜿çšããŠæ°Žå¹³æ¹åã«é 眮ããããšãã§ããŸãïŒ2ã€ã®é åã®å¢çã®å³åŽïŒïŒ
å§ããåã«
ãŠã£ã³ããŠèŠçŽ ïŒ Controlãšããåèªããã³ã³ãããŒã«ãšãåŒã°ããŸãïŒã¯ãã³ã³ããå ãŸãã¯ContentControlã¿ã€ãã®å¥ã®èŠçŽ å ã«é 眮ããå¿ èŠããããŸãã ã³ã³ããã¯ãèªåã®äžã«è€æ°ã®åã³ã³ãããŒã«ãé 眮ããçžäºã®é 眮ã調æŽã§ããç¹å¥ãªã³ã³ãããŒã«ã§ãã ã³ã³ããã®äŸïŒ
- ã°ãªãã -èŠçŽ ãåãšè¡ã«æŽçã§ããŸããååãŸãã¯è¡ã®å¹ ã¯åå¥ã«èšå®ãããŸãã
- StackPanel-åãåäžã®è¡ãŸãã¯åã«é 眮ã§ããŸãã
ä»ã®ã³ã³ããããããŸãã ã³ã³ããã¯ã³ã³ãããŒã«ã§ããããããã³ã³ããå ã«ã¯ãã¹ããããã³ã³ãããå«ããã¹ããããã³ã³ãããªã©ããããŸãã ããã«ãããã³ã³ãããŒã«ãçžäºã«æè»ã«é 眮ã§ããŸãã ãŸããã³ã³ããã®å©ããåããŠããŠã£ã³ããŠã®ãµã€ãºãå€æŽãããšãã«ãã¹ããããã³ã³ãããŒã«ã®åäœãæè»ã«å¶åŸ¡ã§ããŸãã
MVVMããã³INotifyPropertyChangedã€ã³ã¿ãŒãã§ã€ã¹ã ããã¹ãã®ã³ããŒã
ãã®äŸã®çµæã¯ã2ã€ã®ã³ã³ãããŒã«ãåããã¢ããªã±ãŒã·ã§ã³ã«ãªããŸãã1ã€ã¯ããã¹ããç·šéã§ãããã1ã€ã¯ãã¥ãŒã ãã§ãã ãããã®ããå¥ã®ãã®ãžã®å€æŽã¯ã bindingã䜿çšããŠããã¹ããæ瀺çã«ã³ããŒããããšãªãåæçã«è»¢éãããŸãã
ãããã£ãŠãæ°ããäœæãããããžã§ã¯ãïŒ Ex1ãšããååïŒããããã¬ã€ã¢ãŠããšãã£ã¿ãŒã«ç§»åããŠãæåã«æ¢å®ã®ã³ã³ãããŒïŒ <Grid> </ Grid> ïŒã<StackPanel> </ StackPanel>ã«çœ®ãæããŸã ã ãã®ã³ã³ããã§ååã§ã äžäžã«2ã€ã®ã³ã³ãããŒã«ã®ã¿ãé 眮ããå¿ èŠããããŸãã ããããã£Orientation = "Vertical"ãè¿œå ããŠãã³ã³ããŒãã³ãã®é 眮æ¹æ³ãæ瀺çã«æå®ããŸãã ããã«ã¹ã¿ãã¯å ã«ããã€ãã®èŠçŽ ãè¿œå ããŸããããã¹ããå ¥åãããã£ãŒã«ããšããã¹ãã衚瀺ãããã£ãŒã«ãã§ãã ãããã®ã³ã³ãããŒã«ã«ã¯åã蟌ã¿ã³ãŒããå«ãŸããªããããèªå·±çµäºã¿ã°ã§èšè¿°ã§ããŸãïŒä»¥äžã®ã³ãŒããåç §ïŒã äžèšã®ãã¹ãŠã®æé ã®åŸãã³ã³ãããšãã¹ããããã³ã³ãããŒã«ãèšè¿°ããã³ãŒãã¯æ¬¡ã®åœ¢åŒããšãå¿ èŠããããŸãã
<StackPanel Orientation="Vertical"> <TextBox /> <TextBlock /> </StackPanel>
次ã«ããã®äŸã®ç®çã«çŠç¹ãåœãŠãŸãããã ããã¹ãããã¯ã¹ã«å ¥åãããšãã«ãæ瀺çãªã³ããŒæäœãé¿ããªãããåãããã¹ããããã¹ããããã¯ã«åæããŠè¡šç€ºãããããã«ããŸãã äœããã®çš®é¡ã®æ¥ç¶ãšã³ãã£ãã£ãå¿ èŠã§ããããã§ã¯ãåè¿°ã®bindingãªã©ã®ããšã説æããŸãã WPFã®çšèªã§ã®ãã€ã³ãã£ã³ã°ã¯ãã³ã³ãããŒã«ã®äžéšã®ããããã£ãCïŒã¯ã©ã¹ãªããžã§ã¯ãã®äžéšã®ããããã£ã«é¢é£ä»ãããã³ãã«ã®äžéšãå€æŽããããšãã«ãããã®ããããã£ãçžäºã«æŽæ°ã§ããã¡ã«ããºã ã§ãïŒããã¯ãäžæ¹ãä»æ¹ããŸãã¯äž¡æ¹ã®æ¹åã§åæã«æ©èœããŸãïŒã Qtã«ç²ŸéããŠãã人ã®ããã«ãã¹ããããšä¿¡å·ã®é¡æšãæãããšãã§ããŸãã æéã䌞ã°ããªãããã«ãã³ãŒãã«ç§»ããŸãããã
ãããã£ãŠããã€ã³ãã£ã³ã°ãæŽçããã«ã¯ãã³ã³ãããŒã«ã®ããããã£ãšç¹å®ã®CïŒã¯ã©ã¹ã®ããããã£ãå¿ èŠã§ãã æåã«ãXAMLã³ãŒããææ¡ããŸãããã äž¡æ¹ã®ã³ã³ãããŒã«ã®ããã¹ãã¯Textããããã£ã«ä¿åãããããããããã®ããããã£ã®ãã€ã³ãã£ã³ã°ãè¿œå ããŸãã ããã¯æ¬¡ã®ããã«è¡ãããŸãã
<TextBox Text="{Binding}"/> <TextBlock Text="{Binding}"/>
ãã€ã³ãã£ã³ã°ãäœæããŸããããä»ã®ãšããäœãæ確ã§ã¯ãããŸãã:)ãã€ã³ãã£ã³ã°ãè¡ãããã¯ã©ã¹ã®ãªããžã§ã¯ããšãã®ãªããžã§ã¯ãã®ããããã£ãå¿ èŠã§ãïŒåœŒããèšãããã«ããã€ã³ãããå¿ èŠããããŸãïŒã
ããã§ããã®ã¯ã©ã¹ã¯äœã§ããïŒ ãã®ã¯ã©ã¹ã¯ãã¥ãŒã¢ãã«ãšåŒã°ãããã¥ãŒïŒã€ã³ã¿ãŒãã§ã€ã¹ãŸãã¯ãã®éšåïŒãšã¢ãã«ïŒã¢ãã«ãã€ãŸãã¢ããªã±ãŒã·ã§ã³ããžãã¯ãæ åœããã³ãŒãã®éšåïŒéã®ãªã³ã¯ãšããŠæ©èœããŸããããã«ããïŒããçšåºŠãŸã§ã ïŒã€ã³ã¿ãŒãã§ã€ã¹ïŒãã¥ãŒïŒããã®ã¢ããªã±ãŒã·ã§ã³ããžãã¯ã¯ã Model-View-ViewModelïŒMVVMïŒãã¿ãŒã³ãšåŒã°ããWPFã§ã¯ããã®ã¯ã©ã¹ã¯DataContextãšãåŒã°ããŸãã
ãã ããåã«ãã¥ãŒã¢ãã«ã¯ã©ã¹ãèšè¿°ããã ãã§ã¯ååã§ã¯ãããŸããã ãã¥ãŒã¢ãã«ããããã£ãŸãã¯ãã¥ãŒããããã£ãå€æŽãããããšããã€ã³ãã¡ã«ããºã ã«äœããã®æ¹æ³ã§éç¥ããå¿ èŠããããŸãã ããã«ã¯ã PropertyChangedã€ãã³ããå«ãç¹å¥ãªINotifyPropertyChangedã€ã³ã¿ãŒãã§ã€ã¹ããããŸãã åºæ¬ã¯ã©ã¹BaseViewModelã®ãã¬ãŒã ã¯ãŒã¯ã§ãã®ã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ããŸã ã å°æ¥çã«ã¯ãã€ã³ã¿ãŒãã§ã€ã¹ã®å®è£ ãè€è£œããªãããã«ããã®åºæ¬ã¯ã©ã¹ãããã¹ãŠã®ãã¥ãŒã¢ãã«ãç¶æ¿ããŸãã ãã®ããã ViewModelsãã£ã¬ã¯ããªããããžã§ã¯ãã«è¿œå ãã BaseViewModel.csãã¡ã€ã«ããã®ãã£ã¬ã¯ããªã«è¿œå ããŸã ã 次ã®ãããžã§ã¯ãæ§é ãåŸãããŸãã
ããŒã¹ãã¥ãŒã¢ãã«ã®å®è£ ã³ãŒãïŒ
using System.ComponentModel; namespace Ex1.ViewModels { public class BaseViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } }
MainWindowã¯ã©ã¹ã®ãã¥ãŒã¢ãã«ãäœæããããŒã¹ã¢ãã«ããç¶æ¿ããŸãã ãããè¡ãã«ã¯ãåãViewModelsãã£ã¬ã¯ããªã§ã MainWindowViewModel.csãã¡ã€ã«ãäœæããŸãããã®ãã¡ã€ã«ã«ã¯ã次ã®ãããªã³ãŒããå«ãŸããŸãã
namespace Ex1.ViewModels { public class MainWindowViewModel : BaseViewModel { } }
ãããïŒ æ¬¡ã«ããã®ãã¥ãŒã¢ãã«ã«ããããã£ãè¿œå ããå¿ èŠããããŸãããã®ããããã£ã«ã³ã³ãããŒã«ã®ããã¹ãããã€ã³ãããŸãã ããã¯ããã¹ãã§ããããããã®ããããã£ã®ã¿ã€ãã¯stringã§ããå¿ èŠããããŸã ã
public string SynchronizedText { get; set; }
ãã®çµæããã®ãããªã³ãŒããååŸããŸã
namespace Ex1.ViewModels { public class MainWindowViewModel : BaseViewModel { public string SynchronizedText { get; set; } } }
ã ããã圌ãã¯ãããããããã§ãã ãã¥ãŒãããã®ããããã£ã«ãã€ã³ãããããã«æ®ããæºåãã§ããŠããŸãã ä»ãããã£ãŠã¿ãŸãããïŒ
<TextBox Text="{Binding Path=SynchronizedText}"/> <TextBlock Text="{Binding Path=SynchronizedText}"/>
Nishtyakããããžã§ã¯ããéå§ããããã¹ãããã¯ã¹ã«iiiiiãšå ¥åããŸã...äœãèµ·ãããŸããïŒïŒïŒãŸããããã¯å€§äžå€«ã§ããå®éãæ£ããæ¹æ³ã§é²ãã§ããŸãããæ£ãããã€ã³ãã«å°éããŠããŸããã
ãã°ããç«ã¡æ¢ãŸã£ãŠãäœãæ¬ ããŠããã®ããèããŠã¿ãŸãã ãã¥ãŒããããŸãã ãã¥ãŒã¢ãã«ãã zabindiliã®ãããªããããã£ã ç®çã®ã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ãããŸãã åããªããã¹ãè¡ãã³ããŒããããã«å€ãã®ä»äºãããŸãããããªããããå¿ èŠãªã®ã§ãããã????ïŒïŒïŒ111
ããŠãåè«ã¯ããŠããã ãã¥ãŒã¢ãã«ãªããžã§ã¯ããšä»ã®äœããäœæããã®ãå¿ããŸããïŒããã«ã€ããŠã¯åŸã§èª¬æããŸãïŒã ã¯ã©ã¹èªäœã«ã€ããŠèª¬æããŸãããããã®ã¯ã©ã¹ã®ãªããžã§ã¯ãããªããããããã¯äœã®æå³ããããŸããã ããŠããã®ãªããžã§ã¯ããžã®ãªã³ã¯ãã©ãã«ä¿åããå¿ èŠããããŸããïŒ äŸã®å§ãã«è¿ããšããã§ãWPFã§äœ¿çšãããç¹å®ã®DataContextã«ã€ããŠèšåããŸããã ãã®ãããã©ã®ãã¥ãŒã«ãDataContextããããã£ããããããã«ãªã³ã¯ããã¥ãŒã¢ãã«ã«å²ãåœãŠãããšãã§ããŸãã ãã£ãŠã¿ãŸãããã ãããè¡ãã«ã¯ã MainWindow.xamlãã¡ã€ã«ãéããF7ãæŒããŠãã®ãã¥ãŒã®ã³ãŒããéããŸãã ã»ãšãã©ç©ºã§ããŠã£ã³ããŠã¯ã©ã¹ã³ã³ã¹ãã©ã¯ã¿ãŒã®ã¿ããããŸãã ãã¥ãŒã¢ãã«ã®äœæãããã«è¿œå ãããŠã£ã³ããŠã®DataContextã«é 眮ããŸãïŒç®çã®ããŒã ã¹ããŒã¹ã䜿çšããŠè¿œå ããããšãå¿ããªãã§ãã ããïŒã
public MainWindow() { InitializeComponent(); this.DataContext = new MainWindowViewModel(); }
ç°¡åã§ããããããã§ãååã§ã¯ãããŸããã§ããã ããã§ããã¢ããªã±ãŒã·ã§ã³ã®èµ·åæã«ã¯ãããã¹ãã®åæã¯çºçããŸããã ä»ã«äœãããå¿ èŠããããŸããïŒ
SynchronizedTextããããã£ãå€æŽããããšãã«PropertyChangedã€ãã³ããçºçããããã®ã€ãã³ããç£èŠããå¿ èŠãããããšããã¥ãŒã«éç¥ããå¿ èŠããããŸãã ãã®ãããã€ãã³ããããªã¬ãŒããã«ã¯ããã¥ãŒã¢ãã«ã³ãŒããå€æŽããŸãã
public class MainWindowViewModel : BaseViewModel { private string _synchronizedText; public string SynchronizedText { get => _synchronizedText; set { _synchronizedText = value; OnPropertyChanged(nameof(SynchronizedText)); } } }
ããã§äœãããŸãããïŒ ããã¹ããæ ŒçŽããããã®é衚瀺ãã£ãŒã«ããè¿œå ããæ¢åã®ããããã£ã«ã©ããããŸãããã®ããããã£ãå€æŽãããšãã¯ãé衚瀺ãã£ãŒã«ããå€æŽããã ãã§ãªããããŒã¹ãã¥ãŒã¢ãã«ã§å®çŸ©ãããOnPropertyChangedã¡ãœãããåŒã³åºããããŒã¹ã§ãå®è£ ãããINotifyPropertyChangedã€ã³ã¿ãŒãã§ã€ã¹ã§å®£èšãããPropertyChangedã€ãã³ããçºçãããŸãã¢ãã«ã衚瀺ããŸãã ããã¹ããå€æŽããããã³ã«PropertyChangedã€ãã³ããçºçããå€æŽããããã¥ãŒã¢ãã«ã®ããããã£ã®ååãæž¡ãããŸãã
ãŸããã»ãŒãã¹ãŠããã£ããã·ã¥ã©ã€ã³ïŒ PropertyChangedã€ãã³ãããªãã¹ã³ãããã¥ãŒãæå®ããããã«æ®ããŸãã
<TextBox Text="{Binding Path=SynchronizedText, UpdateSourceTrigger=PropertyChanged, Mode=OneWayToSource}"/> <TextBlock Text="{Binding Path=SynchronizedText, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"/>
ã©ã®ããªã¬ãŒã«ãã£ãŠæŽæ°ãè¡ãããã¹ããã瀺ãããšããäºå®ã«å ããŠããã®æŽæ°ã远跡ãããæ¹åïŒãã¥ãŒããã¢ãã«ãžããŸãã¯ãã®éïŒã瀺ããŸããã ããã¹ãããã¯ã¹ã«ããã¹ããå ¥åããããããã¥ãŒã®å€æŽã®ã¿ã«é¢å¿ãããããã OneWayToSourceã¢ãŒããéžæããŸãã ããã¹ããããã¯ã®å Žåããã¹ãŠãæ£å察ã§ãããã¥ãŒã«è¡šç€ºããããã«ãã¥ãŒã¢ãã«ã®å€æŽã«é¢å¿ãããããã OneWayã¢ãŒããéžæããŸãã å€æŽãäž¡æ¹åã§è¿œè·¡ããå Žåã ModeããŸã£ããæå®ããããšãã TwoWayãæ瀺çã«æå®ããããšãã§ããŸããã
ã ãããããã°ã©ã ãå®è¡ããããã¹ããå ¥åããvoi-laïŒ ããã¹ãã¯åæçã«å€æŽãããã©ãã«ãäœãã³ããŒããŸããã§ããïŒ
ç¶ããŠãããŠããããšãã DataTemplateãšCommandãã¿ãŒã³ãæ±ããŸãã