Страницы

Поиск по вопросам

воскресенье, 8 марта 2020 г.

Отображение процесса происходящего внутри функции

#c_sharp #wpf #mvvm


Не знаю как точно сформулировать вопрос.

Есть функция, которая выполняет какие-то действия. Она находится в "библиотеке классов".
Я подключаю эту библиотеку к своему приложению. Запускаю эту функцию и хочу, чтобы
в ProgressBar отображался ход выполнения этой процедуры из библиотеки. Как это правильно
реализовать в подходе MVVM?

UPD: Вот пример по методу Vlad:
Функция в библиотеке:

using System;

namespace ClassLib
{
    public static class Service
    {
        public static void Foo(IProgress progress)
        {
            progress.Report(1);    
            string s;
            for (int i = 1; i <= 99; i++)
            {                    
                for (int j = 0; j <= 50000; j++)
                     s = j.ToString();                    
                progress.Report(i);
            }    
            progress.Report(100);
        }
    }
}


ViewModel:

public class MainWindowViewModel: INotifyPropertyChanged
    {
        private int _progr;
        public int Progress {
            get { return _progr; }
            set { _progr = value;OnPropertyChanged("Progress"); } }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string name) =>            
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));  
         


        public void StartFoo()
        {
            Service.Foo(new Progress(persent => Progress = persent));
        }

    }


View:
XAML


        
    
...



c# code:

private void button_Click(object sender, RoutedEventArgs e)
{
    MainWindowViewModel vm = (MainWindowViewModel)this.DataContext;
    vm.StartFoo();
}


Процесс отображается так : 0 пауза 100 %.
    


Ответы

Ответ 1



Я бы посоветовал в следующее: 1.В библиотечный метод добавить параметр типа IProgress. public class Service { public void Foo(IProgress progress) { progress.Report(1); DoSomeWork(); progress.Report(100); } } 2.В модель представления добавить свойство Progress и обработчик изменения прогресса public class ViewModel { public int Progress { get; set; } // при установке значения вызывает PropertyChanged private void HandleProgressChanged(int progress) { Progress = progress; } private void StartFoo() { Service.Foo(new Progress(HandleProgressChanged)); } } 3.В представлении привязаться к свойству Progress. UPD Ну да. Я слишком упростил пример. Ваш код синхронный. Он выполняется в UI-потоке. Поэтому подвисает интерфейс окна. Его нужно запускать асинхронно: сделать библиотечный метод async или запускать его через Task.Run. Например, так: public static async Task Foo(IProgress progress) { progress.Report(1); string s; for (int i = 1; i <= 99; i++) { for (int j = 0; j <= 50000; j++) s = j.ToString(); await Task.Delay(1);// это просто имитация бурной деятельности progress.Report(i); } progress.Report(100); } public async Task StartFoo() { await Service.Foo(new Progress(persent => Progress = persent)); } private async void button_Click(object sender, RoutedEventArgs e) { MainWindowViewModel vm = (MainWindowViewModel)this.DataContext; await vm.StartFoo(); } Еще я бы посоветовал использовать команды, а не обработчики нажатия кнопок.

Комментариев нет:

Отправить комментарий