-->

Notify PropertyChanged after object update

2019-09-09 06:00发布

问题:

I wish to update my listview in an elegant way.

This is my code:

ObservableCollection<Track> tracks = new ObservableCollection<Track>();
Track track = new Track();
Tracks.AddRange(track); // collection add a track, and list view updates too
Task.Factory.StartNew(() =>
    track.GetInfo(); // this operation might require some times to update
    // here I need to notify that my object is updated
);

How i can force to update binding of an object inside my ObservableCollection ?

This is my userControl.xaml

<UserControl.Resources>
    <local:TimeConverter x:Key="timeConverter" />
    <local:IndexConverter x:Key="indexConverter" />
    <CollectionViewSource x:Key="trackList" Source="{Binding Path=TrackList.Tracks}"/>
</UserControl.Resources>

<DockPanel LastChildFill="True">
    <StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom" Margin="2, 5, 2, 5">
        <Button Name="btn_addtrack" Command="{Binding AddTrack}" Content="+" />
    </StackPanel>
    <ListView Name="lv_tracklist" 
              DataContext="{StaticResource trackList}" 
              ItemsSource="{Binding}"
              >
        <ListView.View>
            <GridView>
                <GridViewColumn Header="#" Width="20" DisplayMemberBinding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}, Converter={StaticResource indexConverter}}" />
                <GridViewColumn Header="Title" DisplayMemberBinding="{Binding Title}"/>
                <GridViewColumn Header="Artist" DisplayMemberBinding="{Binding Artist}"/>
                <GridViewColumn Header="Length" DisplayMemberBinding="{Binding Length, Converter={StaticResource timeConverter}}" />
                <GridViewColumn Header="Path" DisplayMemberBinding="{Binding Location}"/>
            </GridView>
        </ListView.View>
    </ListView>
</DockPanel>

回答1:

If you are opposed to implementing INotifyPropertyChanged you could set the binding to null then rebind but that is not what I would reccomend.

See this answer for notify all

notify-all-properties-of-the-view-model-has-changed

Unless you are changing all the properties I would go with the answer from Miklos. There is overhead to NotifyPropertyChanged.

Recommended pattern

   private string prop1

   Public string Prop1
   {
        get { return prop1; }
        set 
        {
            if (prop1 == value) return;
            prop1 = value;
            NotifyProperyChanged("Prop1");
        }
   {

Yes lines of code but then the UI only paints what has changed.

I just saw the update to your question and your comment.
An update to ALL is an update to each property.
The UI receives notification at the property level.
You only have 5 properties.



回答2:

Your Track class needs to implement the INotifyPropertyChanged interface.

Raise the PropertyChanged event in the setter of every property (after you set the new value) you want to send notification.