MAUI: как запустить длительную операцию и оставить отзыв о ходе выполнения в пользовательском интерфейсе?C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 MAUI: как запустить длительную операцию и оставить отзыв о ходе выполнения в пользовательском интерфейсе?

Сообщение Anonymous »

Я хочу реализовать простой способ выполнения длительной операции (т. е. синхронизации базы данных центрального сервера с локальной базой данных на устройстве) и иметь визуальную обратную связь по пользовательскому интерфейсу о ходе выполнения.
Операция может быть инициирована модальной страницей контента (Navigation.PushAsync), чтобы пользователь не мог больше ничего делать во время синхронизации (кроме отмены, но это не включено в пример), и в то же время он мог сигнал о ходе операции.
Сама операция реализована в классе, который вызывает события для сигнализации о ее ходе.
Я новичок в MAUI, и несколько дней боролся, прежде чем нашел сложную задачу. рабочее решение (пользовательский интерфейс никогда не обновлялся!), пытаясь максимально соответствовать MVVM.
Я хотел бы знать, есть ли лучший и более чистый способ сделать это.
Вот реализация (с использованием CommunityToolkit.MVVM):
  • класс, используемый для обмена информацией о ходе работы
public class ProgressInfo
{
///
/// progress percentage (between 0 and 1)
///
public double ProgressPerc { get; set; } = 0;
///
/// possible extra information related to the progress of the executing operation
///
public object ProgressData { get; set; }
}
  • класс, выполняющий длительную операцию (просто поддельный образец)
public class SyncService
{
private ProgressInfo _progressInfo = new ProgressInfo() { ProgressPerc=0, ProgressData="Sync in progress..."};

// event for communicating operation progress
public event EventHandler ProgressChanged;
protected virtual void OnProgressChanged(ProgressInfo progress)
{
ProgressChanged?.Invoke(this, progress);
}

// main operation
public async Task ReceiveFromServerAsync(DateTime StartDate)
{
//------ simulate long running operation ---------------------------
for (int i = 0; i = 1);
if (progress.ProgressData != null)
{
ProgressMessage = progress.ProgressData.ToString();
}
}

// this method can be called directly by the code behind in the view
public async void DoSyncWithProgress(IProgress progress)
{
Progress = progress;
bool ret = await Sync.ReceiveFromServerAsync(DateTime.Now);
}

private void Sync_ProgressChanged(object sender, ProgressInfo e)
{
//IMPORTANT NOTE:
// if I directly change here the value of ProgressPerc property, the view is not updated

// use the IProgress object in order to report the progress of the operation
if (Progress != null) Progress.Report(e);
}

}
  • код страницы
public partial class DataSyncPage : ContentPage
{

DataSyncVModel vm;

public DataSyncPage()
{
InitializeComponent();
vm = new DataSyncVModel();
BindingContext = vm;
}

// OnNavigatedTo: the page is visible
protected async override void OnNavigatedTo(NavigatedToEventArgs args)
{
base.OnNavigatedTo(args);
//IMPORTANT: here we are in the UI thread, so the lambda will be executed in the UI thread too
var progress = new System.Progress(progressValue =>
{
//call a method in the ViewModel, that will update the properties
//that are used as binding sources in the view
vm.ChangeProgressPerc(progressValue);
});
await Task.Run(() => vm.DoSyncWithProgress(progress));
}

private async void btnClose_Clicked(object sender, EventArgs e)
{
await Navigation.PopModalAsync();
}
}


Подробнее здесь: https://stackoverflow.com/questions/791 ... ack-on-the
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»