#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(IProgressprogress) { 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(); } Еще я бы посоветовал использовать команды, а не обработчики нажатия кнопок.
Комментариев нет:
Отправить комментарий