Pankaj Potdar
Pankaj Potdar

Reputation: 39

INotifyPropertyChanged is not working, data binding in WPF

I am adding some data in listbox and using Inotifypropertychanged to notify, Its very simple code but its not working, after clicking button data in listbox does not change

My xaml

<Grid>
    <StackPanel Orientation="Horizontal" >
        <ListBox x:Name="listbox1" Width=" 250" ItemsSource="{Binding listoffiles}" >

        </ListBox>
        <Button x:Name="btntest" Width=" 50" Height=" 20" VerticalAlignment="Top" Margin=" 10" Content=" Test it"></Button>
        <TextBox x:Name="textbox1" Height=" 50" Width=" 100"  Margin="0,135" Text="{Binding text}"/>
    </StackPanel>
</Grid> </Window>

My viewmodiel class

> `Imports System.Collections.ObjectModel Imports System.ComponentModel`
> 
> 

    Public Class testdata
    >     Implements INotifyPropertyChanged

> 
>     Public Property listoffiles As List(Of String)
>         Get
>             Return _listoffiles
>         End Get
>         Set(value As List(Of String))
>             _listoffiles = value
>             onpropertchange("listoffiles")
>         End Set
>     End Property
> 
>     Public Property text As String
>         Get
>             Return _text
>         End Get
>         Set(value As String)
>             _text = value
>             onpropertchange("text")
>         End Set
>     End Property
> 
> 
>     Private _listoffiles As New List(Of String)
>     Private _text As String
> 
>     Public Sub New()
>         _listoffiles.Add("One")
>         _listoffiles.Add("One")
>         _listoffiles.Add("One")
>         
>     End Sub
> 
>     Protected Sub onpropertchange(name As String)
>         RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
>     End Sub
> 
>     Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged End Class

My view.vb

> Class MainWindow
>    
> 
>     Private Property viewmodel As testdata = New testdata
>     Private Sub btntest_Click(sender As Object, e As RoutedEventArgs) Handles btntest.Click
>         viewmodel.listoffiles.Add("two")
>         viewmodel.listoffiles.Add("two")
>         viewmodel.listoffiles.Add("two")
>         viewmodel.listoffiles.Add("two")
>         viewmodel.listoffiles.Add("two")
>         
> 
>         Dim listoffiles As List(Of String) = viewmodel.listoffiles
>     End Sub End Cla

ss

Upvotes: 0

Views: 985

Answers (2)

mrsargent
mrsargent

Reputation: 2442

You need to change the List to be an ObservableCollection. ObservableCollection has an event called NotifyCollectionChanged. This event is raised when calling methods such as Add(), Remove(), etc that updates the collection.

So you need to make the following code changes for this to work

  1. change the listoffiles to a public property
  2. set the datacontext in the constructor of MainWindow
  3. set the listoffiles to equal viewmodel.listoffiles in constructor of MainWindow

below is a working version of the code you posted above

Class MainWindow

Public Sub New()
    InitializeComponent()
    DataContext = Me
    listoffiles = viewmodel.listoffiles
End Sub
Private Property viewmodel As testdata = New testdata
Public Property listoffiles As New ObservableCollection(Of String)

Private Sub btntest_Click(sender As Object, e As RoutedEventArgs) Handles bnttest.Click
    viewmodel.listoffiles.Add("two")
    viewmodel.listoffiles.Add("two")
    viewmodel.listoffiles.Add("two")
    viewmodel.listoffiles.Add("two")
    viewmodel.listoffiles.Add("two")
End Sub
End Class



Public Class testdata
    Implements INotifyPropertyChanged


Public Property listoffiles As ObservableCollection(Of String)
    Get
        Return _listoffiles
    End Get
    Set(value As ObservableCollection(Of String))
        _listoffiles = value
    End Set
End Property

Public Property text As String
    Get
        Return _text
    End Get
    Set(value As String)
        _text = value

    End Set
End Property


Private _listoffiles As New ObservableCollection(Of String)
Private _text As String

Public Sub New()
    _listoffiles.Add("One")
    _listoffiles.Add("One")
    _listoffiles.Add("One")
End Sub

Protected Sub onpropertchange(name As String)
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
End Sub

Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
End Class

Upvotes: 2

Danielle
Danielle

Reputation: 490

Try updating your binding as follows...

ItemsSource="{Binding listoffiles, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

Your binding probably works correctly for the initial pass, but it's not staying updated with the property.

Upvotes: 0

Related Questions