The error message is the best indicator of what is required.
WPF Data Binding[
^] is far superior and simpler to the WinForm Data Binding system. Once you invest the time to learn how data binding works in WPF, you won't want to look back.
Here is an example for you to show you quickly how Data Binding works:
WPF Binding for property updates requires a
PropertyChanged
event to be fired for each property. For collections, we can use a specialized collection class called
ObservableCollection
which fires a
CollectionChanged
event.
For the properties, below is a base class to simplify the repetitive code required for each property in a class:
Public MustInherit Class ObservableBase
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler _
Implements INotifyPropertyChanged.PropertyChanged
Public Sub [Set](Of TValue)(ByRef field As TValue, ByVal newValue As TValue,
<CallerMemberName> ByVal Optional propertyName As String = "")
If EqualityComparer(Of TValue).[Default].Equals(field, Nothing) OrElse Not field.Equals(newValue) Then
field = newValue
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End If
End Sub
End Class
For this example, I will use a
PersonModel
class which inherits the
ObservableBase
base class above:
Public Class PersonModel
Inherits ObservableBase
Private mName As String
Public Property Name As String
Get
Return mName
End Get
Set(ByVal value As String)
[Set](mName, value)
End Set
End Property
Private mAge As Integer
Public Property Age As Integer
Get
Return mAge
End Get
Set(ByVal value As Integer)
[Set](mAge, value)
End Set
End Property
End Class
Now we can create our collection and add a
event to demonstrate the binding system in action:
Imports System.Collections.ObjectModel
Class MainWindow
Public Sub New()
InitializeComponent()
DataContext = Me
Mock()
End Sub
Public Property Persons As ObservableCollection(Of PersonModel) = New ObservableCollection(Of PersonModel)()
Private rand As Random = New Random()
Private Sub Mock()
For i As Integer = 0 To 10 - 1
Persons.Add(New PersonModel With {
.Name = String.Format("Person {0}", i),
.Age = rand.[Next](20, 50)
})
Next
End Sub
Private Sub Button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
For Each person In Persons
person.Age = rand.[Next](20, 50)
Next
End Sub
End Class
In the above code-behind page, I set the form's
DataContext
to the code-behind page itself. This will allow the UI (XAML) to see the binding notifications and update the display.
Lastly, we can
bind the
properties of the code-behind to the UI elements:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfSimpleBindingVB"
Title="MainWindow"
WindowStartupLocation="CenterScreen" Height="400" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.Resources>
<DataTemplate DataType="{x:Type local:PersonModel}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" Margin="10 3"/>
<TextBlock Text="{Binding Age}" Margin="10 3"
Grid.Column="1"/>
</Grid>
</DataTemplate>
</Grid.Resources>
<ListBox ItemsSource="{Binding Persons}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<Button Content="Randomize" Padding="10 5" Margin="10"
HorizontalAlignment="Center" VerticalAlignment="Center"
Grid.Row="1" Click="Button_Click"/>
</Grid>
</Window>
The above example uses a ListBox control. The principles for the ListView is exactly the same. Here is the UI using the ListView instead:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfSimpleBindingVB"
Title="MainWindow"
WindowStartupLocation="CenterScreen" Height="400" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListView ItemsSource="{Binding Persons}">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Age" DisplayMemberBinding="{Binding Age}" />
</GridView>
</ListView.View>
</ListView>
<Button Content="Randomize" Padding="10 5" Margin="10"
HorizontalAlignment="Center" VerticalAlignment="Center"
Grid.Row="1" Click="Button_Click"/>
</Grid>
</Window>
This example is using the same data binding technique used in the MVVM (Model View ViewModel) Design Pattern except the ViewModel is in the code behind. MVVM is a little bit more involved and is beyond the scope of this answer but worthwhile investing the time in learning.