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 件のコメント:
コメントを投稿