You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 14:18:39