Modelの変更をViewへ通知するには?
Model(TestDataクラス)の値をプログラム内部で変更したとしてもView(MainWindow)には反映されない。
反映させるには、ModelからViewへ変更を通知しなければならない。
前回の誤りとして、
・ItemDataクラスからTestDataクラスへの通知は不要。
(前回はTestDataクラスにINotifyインターフェースを実行、ItemDataからTestDataへプロパティの変更通知をしていた)
そんな事は不要で、単にItemDataクラスに System.CompornentModelのINotifyPropertyChangedインターフェースを実装し、変更のあったプロパティの変更通知を出せばよい。
後は何も考えずに、Viewが勝ってに変更通知を受け取り画面を更新してくれる。
■ItemData.vb
次に TestDataクラス、このクラスも同様でTestDataからViewModelへの通知は不要。
なので、前回修正した箇所を元に戻す。
■TestData.vb
ViewModelも前回の修正を元に戻す。
■ ViewModel.vb
プログラムを実行し、DataGrid上のボタンを押すことでチェックボックスの状態が変化するか確認する。
反映させるには、ModelからViewへ変更を通知しなければならない。
前回の誤りとして、
・ItemDataクラスからTestDataクラスへの通知は不要。
(前回はTestDataクラスにINotifyインターフェースを実行、ItemDataからTestDataへプロパティの変更通知をしていた)
そんな事は不要で、単にItemDataクラスに System.CompornentModelのINotifyPropertyChangedインターフェースを実装し、変更のあったプロパティの変更通知を出せばよい。
後は何も考えずに、Viewが勝ってに変更通知を受け取り画面を更新してくれる。
■ItemData.vb
Imports System.ComponentModel Public Class ItemData Implements INotifyPropertyChanged Public Property id As Integer Public Property name As String Public Property subitems As New List(Of SubItemData) Private _checked As Boolean = True Public Property checked As Boolean Get Return _checked End Get Set(value As Boolean) If (value <> _checked) Then _checked = value NotifyPropertyChanged("checked") End If End Set End Property Private Sub NotifyPropertyChanged(ByVal PropertyName As String) RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(PropertyName)) End Sub #Region "INotifyPropertyChanged" Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged #End Region End Class
次に TestDataクラス、このクラスも同様でTestDataからViewModelへの通知は不要。
なので、前回修正した箇所を元に戻す。
■TestData.vb
Imports YamlDotNet.RepresentationModel Public Class TestData Public Property name As String Public Property items As New List(Of ItemData) Public Sub Load() Dim yaml As New YamlStream() Using sr As New System.IO.StreamReader("test.yaml") yaml.Load(sr) End Using Dim children = DirectCast(yaml.Documents(0).RootNode, YamlMappingNode).Children name = DirectCast(children.Item(New YamlScalarNode("name")), YamlScalarNode).Value For Each itemNode In DirectCast(children.Item(New YamlScalarNode("items")), YamlSequenceNode) Dim item As New ItemData() item.id = DirectCast(itemNode.Item(New YamlScalarNode("id")), YamlScalarNode).Value item.name = DirectCast(itemNode.Item(New YamlScalarNode("name")), YamlScalarNode).Value items.Add(item) For Each subItemNode In DirectCast(itemNode.Item(New YamlScalarNode("subitems")), YamlSequenceNode) Dim subitem As New SubItemData() subitem.name = DirectCast(subItemNode.Item(New YamlScalarNode("name")), YamlScalarNode).Value item.subitems.Add(subitem) Next Next End Sub End Class
ViewModelも前回の修正を元に戻す。
■ ViewModel.vb
Public Class ViewModel Public Property Model As New TestData() Private WithEvents _ClickEvent As ClickEventCommand Public ReadOnly Property ClickEvent As ClickEventCommand Get If (_ClickEvent Is Nothing) Then _ClickEvent = New ClickEventCommand() End If Return _ClickEvent End Get End Property Private Sub _ClickEvent_ShowMessage(id As Integer) Handles _ClickEvent.ShowMessage For Each item In Model.items.Where(Function(x) x.id = id) item.checked = item.checked Xor True Next End Sub End Class
プログラムを実行し、DataGrid上のボタンを押すことでチェックボックスの状態が変化するか確認する。
次回記事:
-- 以上 --
VisualBasic, WPF, DataGrid, YAML, MVVM
0 件のコメント:
コメントを投稿