Windows Forms에서 배열의 요소에 바인딩하는 방법

소개



Windows Forms에서 배열의 요소에 바인딩하고 싶을 때가 상당히 있습니다.
같은 컨트롤을 복수 배치했을 경우도, 배열로 관리하는 것이 편한 때가 있습니다.

전제


  • Window.Forms
  • VB 2017
  • .NET Framework 4.6.1

  • 소스 코드



    이런 화면을 확실히 만듭니다.


    빨리 아래 코드.

    Form1.vb
    Imports System.ComponentModel
    
    Public Class Form1
    
        Private VM As New ViewModel
    
        Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            TextBox1.DataBindings.Add(New Binding("Text", VM.Inputs(0), "Value"))
            TextBox2.DataBindings.Add(New Binding("Text", VM.Inputs(1), "Value"))
            TextBox3.DataBindings.Add(New Binding("Text", VM.Inputs(2), "Value"))
        End Sub
    
        Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            VM.Update()
        End Sub
    
        Private Class ViewModel
    
            Public Inputs As t()
    
            Sub New()
                Inputs = {
                     New t With {.Value = "a"},
                     New t With {.Value = "b"},
                     New t With {.Value = "c"}
                }
            End Sub
    
            Sub Update()
                Inputs(0).Value = "1"
                Inputs(1).Value = "2"
                Inputs(2).Value = "3"
            End Sub
    
            Class t
                Implements INotifyPropertyChanged
    
                Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
    
                Private _Value As String
                Property Value As String
                    Get
                        Return _Value
                    End Get
                    Set
                        _Value = Value
                        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(NameOf(Value)))
                    End Set
                End Property
    
            End Class
    
        End Class
    
    End Class
    

    시도하다



    시작 시


    버튼 누르기


    확실히

    무슨 일이야?



    배열 준비



    ViewModel 클래스내에서는, Inputs 의 요소에 대해서 클래스를 지정합니다. 그리고, Inputs 의 요소에 대해서 바인드 하기 때문에, Inputs 자신은 단순한 멤버로 좋습니다.

    바인딩 대상인 ViewModel 내
        Private Class ViewModel
    
            Public Inputs As t()
    
            ' ~~中略~~
    
        End Class
    

    배열의 「요소」가 되는 프로퍼티의 준비



    대신에 Inputs 의 요소에 대해서 지정한 클래스와 그 프로퍼티에 대해서는, 프로퍼티를 준비해, INotifyPropertyChanged 에 의한 PropertyChanged 이벤트를 발화(Raise) 시키도록 합니다.
    예, 요소 자체를 INotifyPropertyChanged를 상속받은 클래스로 만들어 개별 요소에 바인딩 가능한 속성을 설정하는 데 성공했습니다.

    바인딩 대상인 ViewModel 내
        Private Class ViewModel
    
            Public Inputs As t()
    
            ' ~~中略~~
    
            Class t
                Implements INotifyPropertyChanged
    
                Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
    
                Private _Value As String
                Property Value As String
                    Get
                        Return _Value
                    End Get
                    Set
                        _Value = Value
                        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(NameOf(Value)))
                    End Set
                End Property
    
            End Class
    
        End Class
    

    배열과 그 요소의 초기화



    바인딩 대상이 null이면 보통 nullpo됩니다. 제대로 배열과 그 요소를 초기화합시다. 이어서

    배열 초기화
    ' ~~前略~~
    
        Private Class ViewModel
    
            Public Inputs As t()
    
            Sub New()
                Inputs = {
                     New t With {.Value = "a"},
                     New t With {.Value = "b"},
                     New t With {.Value = "c"}
                }
            End Sub
    
            Sub Update()
                Inputs(0).Value = "1"
                Inputs(1).Value = "2"
                Inputs(2).Value = "3"
            End Sub
    
            ' ~~中略~~
    
        End Class
    
    

    바인딩 설정



    폼을 로드할 때 각 텍스트 상자에 대해 ViewModel 클래스의 멤버에 있는 배열 Inputs의 요소와 연결합니다. 물론 개개의 요소에 대해서 바인드 하므로, 배열에의 인덱스는 제대로 결정해 봅시다.

    양식을로드 할 때 처리되는 바인딩 설정
    ' ~~前略~~
    
    Public Class Form1
    
        Private VM As New ViewModel
    
        Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            TextBox1.DataBindings.Add(New Binding("Text", VM.Inputs(0), "Value"))
            TextBox2.DataBindings.Add(New Binding("Text", VM.Inputs(1), "Value"))
            TextBox3.DataBindings.Add(New Binding("Text", VM.Inputs(2), "Value"))
        End Sub
    
        ' ~~中略~~
    
    End Class
    

    이 때 지정된 인덱스에 해당하는 요소가 없으면 오류가 발생합니다.
    그리고 이상한 설정하면 바인딩되지 않았습니다 (3 패)

    안좋은 예__바인딩 설정
    ' ~~前略~~
    Public Class Form1
    
        Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
            ' エラーになる:存在しない(ようにした)インデックスを指定
            TextBox1.DataBindings.Add(New Binding("Text", VM.Inputs(5000), "Value"))
    
            ' エラーになる:プロパティ「名」としてのInputs(2)は存在しない。特に「(2)」が存在しない
            TextBox3.DataBindings.Add(New Binding("Text", VM, "Inputs(2).Value"))
    
            ' エラーにはならないし、初回だけ値は設定されるけど、実はバインドされてない
            TextBox2.DataBindings.Add(New Binding("Text", VM.Inputs(1).Value, "")) 
        End Sub
    
        ' ~~中略~~
    
    End Class
    

    좋은 웹페이지 즐겨찾기