简体   繁体   中英

How do I access a variable from another class to update my ViewModel

I have this application that has a ProgrressBar on it. I also have a class which acts as a DownloadService because it's being used in multiple ViewModels.

As you can see the function DownloadData simulates it downloading something and keeps track of the total amount of data that has been downloaded in percent, it goes from 0 - 100.

How do I make my ProgressBar get that same value as totalDownloaded without passing in the MainWindowViewModel as a parameter.

MainWindow

<Window.DataContext>
        <local:MainWindowViewModel/>
    </Window.DataContext>
    <StackPanel>
        <ProgressBar Height="25"
                     Maximum="100"
                     Value="{Binding ProgressValue}"/>
        <Button HorizontalAlignment="Center"
                Width="100" Height="25"
                Content="Start"
                Command="{Binding StartDownloadCommand}"/>
    </StackPanel>

MainWindowViewModel

class MainWindowViewModel : ObservableObject
    {
        private int _progressValue;

        public int ProgressValue
        {
            get { return _progressValue; }
            set
            {
                _progressValue = value;
                OnPropertyChanged();
            }
        }

        DownloadService ds = new DownloadService();

        public RelayCommand StartDownloadCommand { get; set; }

        public MainWindowViewModel()
        {
            StartDownloadCommand = new RelayCommand(o => { ds.DownloadData(); }, o => true);
        }
    }

And the DownloadService

 class DownloadService
    {
        public void DownloadData()
        {
            int totalDownloaded = 0;

            for (int i = 0; i < 101; i++)
            {
                totalDownloaded++;
                Console.WriteLine(totalDownloaded);
            }
        }
    }

Reference Progress<T> Class

Provides an IProgress<T> that invokes callbacks for each reported progress value.

Refactor the service to depend on IProgress<int> abstraction and use it to report progress

class DownloadService {
    public void DownloadData(IProgress<int> progress = null) {            
        int totalDownloaded = 0;
        for (int i = 0; i < 101; i++) {
            totalDownloaded++;
            progress?.Report(totalDownloaded); // ?. just in case
            Console.WriteLine(totalDownloaded);
        }
    }
}

View model can pass a Progress<int> to the service to get reports of progress updates.

public MainWindowViewModel() {
    StartDownloadCommand = new RelayCommand(o => { 
        var progress = new Progress<int>(value => ProgressValue = value);
        ds.DownloadData(progress); 
    }, o => true);
}

explicitly depending on IProgress<int> avoids having to tightly couple the view model to the service.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM