简体   繁体   中英

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

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM