C# WPF入門-簡単アプリ作成-01
WPFで簡単アプリを作ってみましょう。
- 環境
- 完成予定
- WPFアプリケーションの作成
- Model(Name.cs)の作成
- ViewModel(MainViewModel.cs)の作成
- View(MainWindow.xaml.cs)の作成
- View(MainWindow.xaml)の作成
- 完成
- リンク
完成予定
FirstNameとLastNameを入力するとFullNameが自動的に画面に表示される
FullName = FirstName + LastName
WPFアプリケーションの作成
Modelを参照する
"InputName"プロジェクトの参照
→参照を追加
参照マネージャー
→"InputName.Model"にチェック
→OK
Model(Name.cs)の作成
namespace InputName.Model { public class Name : INotifyPropertyChanged { private string _firstName; private string _lastName; private string _fullName; public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propertyName) { this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public void SetName() { FullName = string.Format("{0} {1}", FirstName, LastName); } public string FirstName { get { return _firstName; } set { if(_firstName != value) { _firstName = value; SetName(); OnPropertyChanged("FirstName"); } } } public string LastName { get { return _lastName; } set { if(_lastName != value) { _lastName = value; SetName(); OnPropertyChanged("LastName"); } } } public string FullName { get { return _fullName; } set { if(_fullName != value) { _fullName = value; OnPropertyChanged("FullName"); } } } } }
ポイント
1.FirstName、LastNameのSetterに"SetName();"を追加
FirstName、LastNameの値を変更した時にFullNameを設定する
裏処理でFullNameを設定する
2.INotifyPropertyChangedを継承
MVVMでは裏処理で値を変更した際に画面に値変更した事を通知しないと値の変更がされません。
そのため"INotifyPropertyChanged"を継承してSetterに
OnPropertyChanged("変数名");
を書くことでModel→ViewModel→Modelへ変更通知がされます。
ViewModel(MainViewModel.cs)の作成
namespace InputName.ViewModel { public class MainViewModel : INotifyPropertyChanged { private Name _name; public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propertyName) { this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public MainViewModel() { _name = new Name(); } public Name Name { get { return _name; } set { if(_name != value) { _name = value; OnPropertyChanged("Name"); } } } } }
ポイント
こちらはポイントは特にないです。
変更通知はModelと同じ
View(MainWindow.xaml.cs)の作成
namespace InputName { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { private MainViewModel _mainViewModel; public MainWindow() { InitializeComponent(); _mainViewModel = new MainViewModel(); DataContext = _mainViewModel; } } }
ポイント
1.DataContext
ViewとViewModelは1対1の関係になっています。
そのViewModelをDataContextさせます。
View(MainWindow.xaml)の作成
<Window x:Class="InputName.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:InputName" mc:Ignorable="d" Title="MainWindow" Height="200" Width="300"> <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center"> <StackPanel Orientation="Horizontal"> <Label Content="FirstName:" Width="70"/> <TextBox Text="{Binding Name.FirstName}" Width="100"/> </StackPanel> <StackPanel Orientation="Horizontal"> <Label Content="LastName:" Width="70"/> <TextBox Text="{Binding Name.LastName}" Width="100"/> </StackPanel> <StackPanel Orientation="Horizontal"> <Label Content="FullName:" Width="70"/> <TextBox Text="{Binding Name.FullName}" Width="100"/> </StackPanel> </StackPanel> </Window>
XAMLは全然わかりにくいですよね。
私も最初は全くわからなかったです。
慣れると案外簡単にXAMLをそのまま変更できます。
XAMLのタグ説明
Label:画面に文字列を表示
Content:表示する内容
Width:Labelの幅
TextBox:入力する箱
Text:Bindingさせる変数
Width:TextBoxの幅
ポイント
1.TextBoxのBinding
WPFで一番重要になるのがこのBindingです。
このBindingさせるパスがまた重要になります。
<TextBox Text="{Binding Name.FirstName}" Width="100"/>
なぜ"{Binding FirstName}"ではなく、"{Binding Name.FirstName}"なのか、
それはDataContextにMainViewModelを入れたからです。
DataContext = _mainViewModel;
MainViewModelから見た時にFirstNameの場所は
"Name.FirstName"をBindingに書きます。
2.そもそもBindingとは・・・
Model、ViewModelの変更をリアルタイにViewに反映させることです。
※リアルタイムかどうかは設定できます。
WPFで一番難しいのが、XAMLとBindingです。
私は今もこの2つに悩まされています。
完成
これで完成です。
今回は簡単にするためにNameのSetterに"SetName()"を書きました。
でもこの書き方はイマイチです。
次はCommandと言うものを使って"SetName()"を呼び出します。
WPFではこのCommandを使うのが一般的です。