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