David Brunelle
David Brunelle

Reputation: 6440

ListView do not get updated even with INotifyPropertyChanged interface

I have a UI element which is a listview that contains in it another listview (one vertical and one horizontal).

The Itemsource of the the First listview is an ObservableCollection of Objects, which in turn contains ObservableCollection of a child object. Both have INotifyPropertyChanged interface implemented and call the PropetyChanged Event when usefull.

If I added new child object, I see my second listview update, but when I change a value, I do not see anything change. Is there anything I must do to refresh my UI element in this case ?

Here is my listview

<ListView x:Name="LstInfoEtape" Margin="0,0,0,0" Style="{StaticResource BaseListView}" Grid.Row="2" Grid.Column="1" >
 <ListView.ItemTemplate>
  <DataTemplate>
   <ListView x:Name="LstEtape" ItemsSource="{Binding LstEtapes}"  Background="#00000000" SelectionChanged="ListView_SelectionChanged" ScrollViewer.ScrollChanged="ListView_ScrollChanged">
    <ListView.ItemsPanel>
     <ItemsPanelTemplate>
      <StackPanel Orientation="Horizontal" />
     </ItemsPanelTemplate>
    </ListView.ItemsPanel>
    <ListView.ItemTemplate>
     <DataTemplate>
      <Border Width="82"  CornerRadius="4" BorderBrush="{Binding ColorSelected}" BorderThickness="3,3,3,3" Visibility="{Binding EtapeVisible}" Background="{Binding ColorBackground}" MouseDown="Border_MouseDown">
       <Grid  Width="80" >
        <Grid.RowDefinitions>
         <RowDefinition Height="19"/>
        </Grid.RowDefinitions>
        <TextBlock Margin="2,0,2,0" x:Name="TxtDateRappel"  TextWrapping="Wrap" Grid.Row="0" Text="{Binding DateRappelTerminaison,StringFormat=yyyy-MM-dd,NotifyOnSourceUpdated=True}" Visibility="{Binding EtapeVisible}" FontSize="12" Foreground="{Binding ColorForeground}" />
       </Grid>
      </Border>
     </DataTemplate>
    </ListView.ItemTemplate>
   </ListView>
  </DataTemplate>
 </ListView.ItemTemplate>
</ListView>

The classes I use are those

Public Class SuiviOperationLite
Implements INotifyPropertyChanged

Private _strNom As String
Private _oLstProcessusLite As ObservableCollection(Of ContratProcessusLite) ' Not implemented yet

Private _oLstEtapeLite As ObservableCollection(Of ContratProcessusEtapeLite)

Public Sub New(ByVal strNom As String,
               ByVal oLstProcessusLite As ObservableCollection(Of ContratProcessusLite),
               ByVal oLstEtapeLite As ObservableCollection(Of ContratProcessusEtapeLite))

    Constructor(strNom, oLstProcessusLite, oLstEtapeLite)

End Sub

Private Sub Constructor(ByVal strNom As String,
                        ByVal oLstProcessusLite As ObservableCollection(Of ContratProcessusLite),
               ByVal oLstEtapeLite As ObservableCollection(Of ContratProcessusEtapeLite))

    _strNom = strNom
    _oLstProcessusLite = oLstProcessusLite
    _oLstEtapeLite = oLstEtapeLite
End Sub

Public Property Nom() As String
    Get
        Return _strNom
    End Get
    Set(ByVal value As String)
        _strNom = value
    End Set
End Property

Public Property LstContratProcessus() As ObservableCollection(Of ContratProcessusLite)
    Get
        Return _oLstProcessusLite
    End Get
    Set(ByVal value As ObservableCollection(Of ContratProcessusLite))
        _oLstProcessusLite = value
    End Set
End Property

Public Property LstEtapes() As ObservableCollection(Of ContratProcessusEtapeLite)
    Get
        Return _oLstEtapeLite
    End Get
    Set(ByVal value As ObservableCollection(Of ContratProcessusEtapeLite))
        _oLstEtapeLite = value
    End Set
End Property

Protected Friend Sub NotifyPropertyChanged(ByVal info As String)      
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
End Sub

Public Event PropertyChanged(sender As Object, e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
End Class


Public Class ContratProcessusEtapeLite
Implements INotifyPropertyChanged

Private _lngId As Long
Private _lngIdSequenceTravail As Long
Private _boolSelected As Boolean
Private _strETapeVisible As String
Private _strColorBackGround As String
Private _strColorForeGround As String
Private _dateRappelTerminaison As Date
Private _oParent As DAL.SuiviOperationLite

Public Sub New(ByVal oParent As DAL.SuiviOperationLite,
               ByVal lngId As Long,
               ByVal lngIdSequenceTravail As Long,
               ByVal boolSelected As Boolean,
               ByVal strEtapeVisible As String,
               ByVal strColorBackGround As String,
               ByVal strColorForeGround As String,
               ByVal dateRappelTerminaison As Date)

    Constructor(oParent,
                lngId, _
                lngIdSequenceTravail, _
                boolSelected, _
                strEtapeVisible, _
                strColorBackGround, _
                strColorForeGround, _
                dateRappelTerminaison)

End Sub

Private Sub Constructor(ByVal oParent As DAL.SuiviOperationLite,
                        ByVal lngId As Long,
                        ByVal lngIdSequenceTravail As Long,
                        ByVal boolSelected As Boolean,
                        ByVal strEtapeVisible As String,
                        ByVal strColorBackGround As String,
                        ByVal strColorForeGround As String,
                        ByVal dateRappelTerminaison As Date)

    _oParent = oParent
    _lngId = lngId
    _lngIdSequenceTravail = lngIdSequenceTravail
    _boolSelected = boolSelected
    _strETapeVisible = strEtapeVisible
    _strColorBackGround = strColorBackGround
    _strColorForeGround = strColorForeGround
    _dateRappelTerminaison = dateRappelTerminaison
End Sub

Public Property Parent() As DAL.SuiviOperationLite
    Get
        Return _oParent
    End Get
    Set(ByVal value As DAL.SuiviOperationLite)
        _oParent = value
    End Set
End Property


Public Property ID() As Long
    Get
        Return _lngId
    End Get
    Set(ByVal value As Long)
        _lngId = value
        NotifyPropertyChanged("ID")
    End Set
End Property

Public Property IdClientContratSequenceTravail() As Long
    Get
        Return _lngIdSequenceTravail
    End Get
    Set(ByVal value As Long)
        _lngIdSequenceTravail = value
        NotifyPropertyChanged("IdSequence")
    End Set
End Property

Public Property Selected() As Boolean
    Get
        Return _boolSelected
    End Get
    Set(ByVal value As Boolean)
        _boolSelected = value
        NotifyPropertyChanged("Selected")
    End Set
End Property

Public ReadOnly Property ColorSelected As String
    Get
        If _boolSelected Then
            Return "#FF4394DF"
        Else
            Return "#FF000000"
        End If
    End Get
End Property

Public Property EtapeVisible() As String
    Get
        Return _strETapeVisible
    End Get
    Set(ByVal value As String)
        _strETapeVisible = value
        NotifyPropertyChanged("Visible")
    End Set
End Property

Public Property ColorBackground() As String
    Get
        Return _strColorBackGround
    End Get
    Set(ByVal value As String)
        _strColorBackGround = value
        NotifyPropertyChanged("Background")
    End Set
End Property

Public Property ColorForeground() As String
    Get
        Return _strColorForeGround
    End Get
    Set(ByVal value As String)
        _strColorForeGround = value
        NotifyPropertyChanged("Foreground")
    End Set
End Property

Public Property DateRappelTerminaison() As Date
    Get
        Return _dateRappelTerminaison
    End Get
    Set(ByVal value As Date)
        _dateRappelTerminaison = value
        NotifyPropertyChanged("DateRappel")
    End Set
End Property

Private Sub NotifyPropertyChanged(ByVal info As String)
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
    _oParent.NotifyPropertyChanged("Child")
End Sub

Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
End Class

And here are the functions (There are more processing to get the collection of items, but I doubt it's really relevant :

Private Sub LoadList(colSuivi as ObservableCollection(Of SuiviProductionLite)
     LstInfoEtape.ItemsSource = colSuivi 
End Sub

Private Sub Border_MouseDown(sender As System.Object, e As System.Windows.Input.MouseButtonEventArgs)
    Dim oBorder As Border


    Dim oEtapeLite As DAL.ContratProcessusEtapeLite

    Select Case e.Source.GetType.ToString
        Case "System.Windows.Controls.TextBlock"
            Dim oTxt As TextBlock = e.Source
            Dim oGrid As Grid = oTxt.Parent
            _oCurBorderDet = oGrid.Parent
        Case "System.Windows.Controls.Border"
            Dim oBrd As Border = e.Source
            _oCurBorderDet = e.Source
    End Select

    If Not _oCurBorderDet.DataContext.GetType().FullName.Equals("MS.Internal.NamedObject") Then
        oEtapeLite = _oCurBorderDet.DataContext
        oEtapeLite.Selected = True            
    End If


End Sub

When I do some tracing, I know that both PropertyChanged Events are call wheter I click on my UI. If I do a manual "Items.Refresh", I can also see the UI being changed, but I want to remove that manual refresh as it refresh everything, not only the item just modified, which, when facing a lot of data, takes much more time.

Upvotes: 0

Views: 472

Answers (1)

paparazzo
paparazzo

Reputation: 45096

I see one problem

Public Property IdClientContratSequenceTravail() As Long
    Get
        Return _lngIdSequenceTravail
    End Get
    Set(ByVal value As Long)
        _lngIdSequenceTravail = value
        NotifyPropertyChanged("IdSequence")
    End Set
End Property

Wrong name in Notify

Upvotes: 1

Related Questions