【问题标题】:Async progress bar in WPF using bindingWPF中使用绑定的异步进度条
【发布时间】:2020-02-19 15:53:45
【问题描述】:

我在可视化 MVVM WPF 进度条时遇到问题。我的主脚本方法运行但进度条根本没有更新。我可以使用提示来获得正确的方向。在我之前的代码中,我得到了使用 Progress<T> (by @Jonathan Willcock) 的提示,但我无法成功实现。

(请注意,这篇文章不是重复的问题,因为上次我使用了按钮单击,但我希望它纯粹在数据绑定上运行)

问题

如何将进度条异步绑定到视图模型中调用的方法?我正在使用 Delegate 命令来调用我的方法,我不想使用按钮单击事件。

我在视图中的内容 - XAML

我这里有两个主要功能,进度条和按钮。按钮启动方法调用成功,但进度条没有加载。

    <ProgressBar Name="pbStatus"
                         Minimum="0"
                         Value="{Binding PrgBarVal, Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"
                         Maximum="100"
                         Height="20"/>
    <Button x:Name = "ApplyButton" Margin="0 1 0 1" Content ="Run software" Command="{Binding RunCalcBtn, Mode=TwoWay}"/>

我在 XAML.cs 中的内容

我从后台工作程序方法中知道的是它尝试异步运行它。我这里有个问题,我在这里添加了一个断点来检查代码是否通过'Window_ContentRendered'方法运行但它没有。

    public partial class UserInterface: UserControl
    {
        public UserInterface()
        {
            InitializeComponent();
        }
        private void Window_ContentRendered(object sender, EventArgs e)
        {
            BackgroundWorker worker = new BackgroundWorker();
            worker.WorkerReportsProgress = true;
            worker.DoWork += worker_DoWork; //Do I need a worker.ProgressChanged here?
            worker.RunWorkerAsync();
        }
        thenamespace.ViewModel.SelectedViewModel get = new thenamespace.ViewModel.SelectedViewModel ();
        void worker_DoWork(object sender, DoWorkEventArgs e)
        {

            for (int i = Convert.ToInt32(get.PrgBarVal); i < 100; i++)
            {
                (sender as BackgroundWorker).ReportProgress(i);
            }
        }
    }

我在视图模型中拥有的东西

在视图模型中,我使用委托命令来调用我的数据绑定方法。

public SelectedViewModel() 是调用 Run() 方法的地方。在Run() 方法中,其中的函数正确运行并正确更新PrgBarVal 的值。但是,这根本不会更新进度条。

    public class SelectedViewModel : ModelView, INotifyPropertyChanged
    {
        public ModelView modelView { get; set; }

        private DelegateCommand _runCalcBtn;
        public DelegateCommand RunCalcBtn
        {
            get { return _runCalcBtn; }
            set
            {
                _runCalcBtn = value;
                SetPropertyChanged("RunCalcBtn"); //Same as RaisedPropertyChanged
            }
        }
        public SelectedViewModel()
        {
            modelView = new ModelView();
            RunCalcBtn = new DelegateCommand(Run);
        }

        private int _prgBarVal;
        public int PrgBarVal
        {
            get { return _prgBarVal; }
            set
            {
                _prgBarVal = value;
                OnPropertyChanged("PrgBarVal"); //Same as RaisedPropertyChanged
            }
        }

        //Main Function
        private async void Run()
        {

            MethodToWork(); //Function that calls other methods to run 
        }

非常感谢您的帮助!

【问题讨论】:

    标签: wpf asynchronous mvvm data-binding progress-bar


    【解决方案1】:

    这是 ViewModel(使用 NuGet ReactiveUI.WPF)

    public class MainViewModel : ReactiveObject
    {
        private int _workProgress;
    
        public MainViewModel()
        {
            IProgress<int> progress = new Progress<int>( e => WorkProgress = e );
            StartWork = ReactiveCommand.CreateFromTask( () => ExecuteStartWorkAsync( progress ) );
    
        }
    
        private async Task ExecuteStartWorkAsync( IProgress<int> progress )
        {
            progress.Report( 0 );
            for ( int i = 0; i < 1000; i++ )
            {
                await Task.Delay( 10 ).ConfigureAwait( false );
                progress.Report( (int)Math.Floor( i / 1000.0 * 100.0 ) );
            }
        }
    
    
        public int WorkProgress { get => _workProgress; private set => this.RaiseAndSetIfChanged( ref _workProgress, value ); }
        public ICommand StartWork { get; }
    }
    

    和视图

    <Window x:Class="WpfApp4.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp4"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Window.DataContext>
            <local:MainViewModel/>
        </Window.DataContext>
        <Grid>
            <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
                <Button Content="Start work" Command="{Binding StartWork}" Width="80"/>
                <ProgressBar Value="{Binding WorkProgress,Mode=OneWay}" Width="120"/>
            </StackPanel>
        </Grid>
    </Window>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多