Мауи с CommunityToolkit ObservableProperty не обновляется во время обработки
У меня есть приложение Maui, работающее только на Android (Zebra Scan-gun).
Когда я нажимаю кнопку на экране, запуск процесса может занять 30 секунд. В течение этих 30 секунд я обновляю значение ObservableProperty, чтобы предоставлять обновления пользователю по мере продолжения обработки. В настоящее время результатом является то, что пользовательский интерфейс не обновляется до тех пор, пока он не вернет управление на экран.
Как я используюCommunityToolkit.Mvvm
вSetProperty
вызывается внутренним кодом, который, как я ожидаю, обновит пользовательский интерфейс.
Вот немного соответствующего кода:
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace myNamespace
{
public partical class MyClassVM: ObservableObject
{
[ObservableProperty]
string status;
[RelayCommand]
void DoStuff()
{
var myUseCase = new DoStuffUseCase();
myUseCase.Execute(UpdateStatus)
}
public void UpdateStatus(string text, bool isThreadRunning)
{
Status = text;
}
}
}
Вот определение моего варианта использования Execute:
public void Execute(Action<string, bool> callback)
{
callback("Begin", true);
// do stuff which sometimes takes a few seconds
callback("End", false);
}
и вот мой XAML:
<Label x:Name="lblStatus"
Text="{Binding Status}"
HorizontalTextAlignment="Center"
FontSize="20"
TextColor="DarkRed"
FontAttributes="Bold"
Margin="0,20,0,0"/>
В результате пользователь никогда не увидит сообщение «Начало». Только сообщение End после завершения процесса.
1 ответ
Вы можете попробовать добавитьasync-await
для функцииExecute
.
Основываясь на вашем коде, я сделал тест, и он работает правильно на моей стороне.
Пожалуйста, обратитесь к следующему коду:
public partial class MyClassVM: ObservableObject
{
[ObservableProperty]
string status;
//[RelayCommand]
public MyClassVM()
{
var myUseCase = new DoStuffUseCase();
myUseCase.Execute(UpdateStatus);
}
public void UpdateStatus(string text, bool isThreadRunning)
{
Status = text;
}
}
internal class DoStuffUseCase
{
public DoStuffUseCase()
{
}
// add async-await here
public async void Execute(Action<string, bool> callback)
{
callback("Begin", true);
// do stuff which sometimes takes a few seconds
await Task.Delay(3000);
callback("End", false);
}
}