c# - 进度条没有更新

标签 c# wpf mvvm binding progress-bar

我遇到了 {Binding CurrentProgress} 的问题Progressbar 的值控制 Listview 内部.在我的代码中,我可以添加一些具有 CurrentProgress 属性的项目属性(property)也是如此。项目以适当的方式添加,但只有一个进度条的更新。这是代码:

模型:

sealed public class Mp3Model : INotifyPropertyChanged
{
    public string Name { get; set; }

    private double _currentProgress;
    public double CurrentProgress
    {
        get
        {
            return _currentProgress;
        }
        set
        {
            _currentProgress = value;
            OnPropertyChanged("CurrentProgress");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

XAML:
<ListView ItemsSource="{Binding Mp3List}">
    <ListView.View>
        <GridView>
            <GridViewColumn
                Width="140"
                DisplayMemberBinding="{Binding Name}"
                Header="Track Name" />
            <GridViewColumn Width="300" Header="Progress">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <Grid Width="320">
                            <ProgressBar
                                Height="40"
                                Margin="10"
                                IsIndeterminate="{Binding IsIndeterminate}"
                                Maximum="100"
                                Minimum="0"
                                Visibility="{Binding IsProgressDownloadVisible}"
                                Value="{Binding CurrentProgress}" />
                            <TextBlock
                                HorizontalAlignment="Center"
                                VerticalAlignment="Center"
                                Text="{Binding CurrentProgress, StringFormat={}{0:0}%}"
                                Visibility="{Binding IsPercentLabelVisible}" />
                            <TextBlock
                                HorizontalAlignment="Center"
                                VerticalAlignment="Center"
                                Text="{Binding ConvertingLabelText}"
                                Visibility="{Binding IsConvertingLabelVisible}" />
                            <TextBlock
                                HorizontalAlignment="Center"
                                VerticalAlignment="Center"
                                Text="{Binding IsOperationDone}"
                                Visibility="{Binding IsOperationDoneLabelVisible}" />
                        </Grid>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

View 模型(方法)
private void SaveVideoToDisk()
{
    Task.Factory.StartNew(() =>
    {
        long currentLocalProgress = 0;
        this._fileHelper = new FileHelper();
        this._model = new Mp3Model();

        using (var service = Client.For(YouTube.Default))
        {
            using (var video = service.GetVideo(YoutubeLinkUrl))
            {
                _fileHelper.DefaultTrackName = video.FullName;
                _fileHelper.DefaultTrackPath = _fileHelper.Path + "\\" + _fileHelper.DefaultTrackName;
                _fileHelper.DefaultTrackHiddenPath = _fileHelper.HiddenPath + "\\" + _fileHelper.DefaultTrackName;
                _fileHelper.TmpTrackPath = _fileHelper.PreparePathForFFmpeg(_fileHelper.DefaultTrackHiddenPath);

                _model = new Mp3Model()
                {
                    Name = _fileHelper.DefaultTrackName,
                    IsProgressDownloadVisible = Visibility.Visible,
                    IsPercentLabelVisible = Visibility.Visible,
                    IsConvertingLabelVisible = Visibility.Hidden,
                    IsOperationDoneLabelVisible = Visibility.Hidden,
                    ConvertingLabelText = Consts.ConvertingPleaseWait,
                    CurrentProgress = 0,
                };

                Application.Current.Dispatcher.BeginInvoke(new Action(() =>
                {
                    this._mp3List.Add(_model);
                }));

                using (var outFile = File.OpenWrite(_fileHelper.TmpTrackPath))
                {
                    using (var progressStream = new ProgressStream(outFile))
                    {
                        var streamLength = (long)video.StreamLength();

                        progressStream.BytesMoved += (sender, args) =>
                        {
                            currentLocalProgress = args.StreamLength * 100 / streamLength;
                            _model.CurrentProgress = currentLocalProgress;
                            Debug.WriteLine($"{_model.CurrentProgress}% of video downloaded");
                        };

                        video.Stream().CopyTo(progressStream);
                    }
                }
                //ExtractAudioFromVideo(_fileHelper.TmpTrackPath);
            }
        }
    });
}

ProgressBar Binded 值的位置:
progressStream.BytesMoved += (sender, args) =>
{
    currentLocalProgress = args.StreamLength * 100 / streamLength;
    _model.CurrentProgress = currentLocalProgress;
    Debug.WriteLine($"{_model.CurrentProgress}% of video downloaded");
};

有人知道吗?

最佳答案

尝试猜测:您更新了一个 _model 字段,每次调用 save video to disk 方法时都会覆盖该字段。这可能仅在类的实例只能完成一次调用此方法的情况下才有效(但由于我们没有类,我们不知道它是列表还是视频)。

所以我会说调用两次该方法会阻止第一个 _model 实例被更新(因为 lambda 捕获了保存对象的变量)

关于c# - 进度条没有更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47798785/

相关文章:

c# - 从在 Mono 上运行的 C# 进程运行 C++ 应用程序。运行检测器错误

c# - DataGrid 中按钮的可见性

c# - ASP.NET GridView 不在数据库中保存更新

wpf - Prism2/MVVM 从 ViewModel 关闭 View

wpf - 在 WinForms 或 WPF 应用程序中编辑 HTML

c# - MVVM + 中介模式 : Registration of Mediator occurs too late

c# - WPF 中 GridViewDataColumn.CellEditTemplate 上的 MVVM 嵌套绑定(bind)

Silverlight MVVM从哪里开始

c# - 是否有必要在 EventHandler.BeginInvoke (C# .Net 3.5) 的回调中调用 EndInvoke

c# - CollectionViewSource 在 XAML 中不能是 DataBound 但在 CodeBehind 中可以吗?