■ VisualBasic+WPF+YAML #13:Modelの変更をViewへ通知する 2

VBからYMALファイルを読み込みたい。
前回記事:VisualBasic+WPF+YAML #12:Modelの変更をViewへ通知する



Modelの変更をViewへ通知するには?

Model(TestDataクラス)の値をプログラム内部で変更したとしてもView(MainWindow)には反映されない。
反映させるには、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 件のコメント:

その他の記事