WPF中ListView内ProgressBar绑定嵌套属性不更新问题
问题:ListView项内ProgressBar绑定不更新
我尝试将ListView项(自定义控件)内ProgressBar的Value绑定到ViewModel中ObservableCollection<VideoDisplayExternal>集合里每个元素的DownloadProgress子属性,目的是下载对应视频时更新进度条。下载过程中VideoDisplayExternal的DownloadProgress值已正常变化(最终能达到100),但ProgressBar完全没有更新。相关代码如下:
下载方法(ViewModel中)
foreach (VideoDisplayExternal videoDisplayExternal in VideoDisplayExternals) { Video video = videoDisplayExternal.Video; var streamInfo = videoDisplayExternal.SelectedStream; string fileName = $"{video.Title}.{streamInfo.Container}"; string downloadPath = System.IO.Path.Combine(playlistFolderPath, fileName); // 此处已生效(VideoDisplayExternal内的进度值已改变)但ProgressBar未更新 CurrentlyDownloadingVideoDisplayExternal = videoDisplayExternal; var progressHandler = new Progress<double>(ShowDownloadProgress); // 下载视频 await youtube.Videos.Streams.DownloadAsync(streamInfo, downloadPath, progressHandler); CurrentlyDownloadingVideoDisplayExternal = null; }
ViewModel属性
public ObservableCollection<VideoDisplayExternal> VideoDisplayExternals { get; set; } private VideoDisplayExternal currentlyDownloadingVideoDisplayExternal; public VideoDisplayExternal CurrentlyDownloadingVideoDisplayExternal { get { return currentlyDownloadingVideoDisplayExternal; } set { currentlyDownloadingVideoDisplayExternal = value; OnPropertyChanged("CurrentlyDownloadingVideoDisplayExternal"); } }
模型定义
public class VideoDisplayExternal { public bool IsCheckBoxChecked { get; set; } public Video Video { get; set; } public List<YoutubeExplode.Videos.Streams.MuxedStreamInfo> Streams { get; set; } public YoutubeExplode.Videos.Streams.MuxedStreamInfo SelectedStream { get; set; } public double DownloadProgress { get; set; } } public class Video { public int Id { get; set; } public int VideoDownloadId { get; set; } public string Title { get; set; } public string Author { get; set; } public string Url { get; set; } public string ThumbnailUrl { get; set; } public TimeSpan? Duration { get; set; } }
ProgressBar绑定(ListView内的UserControl中)
<ProgressBar Grid.Row="1" Margin="10" Maximum="100" Minimum="0" Value="{Binding DownloadProgress, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
解决方法
核心问题是**VideoDisplayExternal类未实现INotifyPropertyChanged接口**。ObservableCollection仅会监听集合元素的添加、移除或替换操作,无法感知元素内部属性的变化。只有当属性变更时触发PropertyChanged事件,UI才能收到更新通知。
1. 让VideoDisplayExternal实现INotifyPropertyChanged
修改模型类,为所有需要绑定的属性添加变更通知:
public class VideoDisplayExternal : INotifyPropertyChanged { private bool _isCheckBoxChecked; public bool IsCheckBoxChecked { get => _isCheckBoxChecked; set { _isCheckBoxChecked = value; OnPropertyChanged(nameof(IsCheckBoxChecked)); } } private Video _video; public Video Video { get => _video; set { _video = value; OnPropertyChanged(nameof(Video)); } } private List<YoutubeExplode.Videos.Streams.MuxedStreamInfo> _streams; public List<YoutubeExplode.Videos.Streams.MuxedStreamInfo> Streams { get => _streams; set { _streams = value; OnPropertyChanged(nameof(Streams)); } } private YoutubeExplode.Videos.Streams.MuxedStreamInfo _selectedStream; public YoutubeExplode.Videos.Streams.MuxedStreamInfo SelectedStream { get => _selectedStream; set { _selectedStream = value; OnPropertyChanged(nameof(SelectedStream)); } } private double _downloadProgress; public double DownloadProgress { get => _downloadProgress; set { _downloadProgress = value; OnPropertyChanged(nameof(DownloadProgress)); } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
2. 确认进度更新方法正确触发属性变更
确保ShowDownloadProgress方法正确更新当前下载项的DownloadProgress属性(该属性现在会触发通知):
private void ShowDownloadProgress(double progress) { if (CurrentlyDownloadingVideoDisplayExternal != null) { // 此处赋值会触发PropertyChanged,通知UI更新ProgressBar CurrentlyDownloadingVideoDisplayExternal.DownloadProgress = progress * 100; } }
完成以上修改后,当DownloadProgress值变化时,UI会自动收到通知并更新ProgressBar的显示。
内容的提问来源于stack exchange,提问作者John Mark David Pintor
相关产品推荐
相关产品推荐

