Пользовательский интерфейс платформы Uno не обновляет загрузчик при обновлении свойства Observable ViewModel
Я разрабатываю клиент, используя Uno Platform и WINUI3 . У меня есть небольшое требование, чтобы показать загрузчик, когда какой-то внешний вызов API выполняется асинхронно для получения данных. На самом деле мне нужна эта функциональность на всех страницах.
Я использую x:Bind для привязки наблюдаемого свойства IsBusy модели представления (используя CommunityToolkit.MVVM 8.0). когда для свойства «IsBusy» установлено значение «true» в асинхронном InvokeCommand, вызванном нажатием кнопки, я ожидаю, что он начнет показывать загрузчик в пользовательском интерфейсе. и как только мой внешний вызов API завершится, я верну его в «false», чтобы загрузчик перестал отображаться.
К сожалению, это не работает должным образом. что мне здесь не хватает? полный код ниже.
MainPage.Xaml:
<Page
x:Class="TestMVVM.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestMVVM"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Page.Resources>
<local:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
</Page.Resources>
<Grid>
<!--<TextBlock Text="Hello, world!" Margin="20" FontSize="30" />-->
<ProgressRing Name="myLoader" Margin="0,0,5,0" Height="50" Width="50" IsActive="{x:Bind ViewModel.IsBusy}"/>
<TextBlock Name="txtLoader" FontWeight="SemiBold" FontSize="25" Text="Loading..." Visibility="{x:Bind ViewModel.IsBusy, Converter={StaticResource BoolToVisibilityConverter}}"/>
<Button Content="CLick me" Command="{x:Bind ViewModel.ItemInvokedCommand}"></Button>
</Grid>
</Page>
MainPage.Xaml.cs:
public sealed partial class MainPage : Page
{
public MainPageViewModel ViewModel { get; } = new MainPageViewModel();
public MainPage()
{
this.InitializeComponent();
//this.DataContext = ViewModel; // i tried to set like this as well but no luck
}
}
ViewModel:
public partial class MainPageViewModel : ObservableObject
{
private IAsyncRelayCommand _itemInvokedCommand;
public IAsyncRelayCommand ItemInvokedCommand => _itemInvokedCommand ?? (_itemInvokedCommand = new AsyncRelayCommand<TypedEventHandler<object, object>>(OnItemInvoked));
[ObservableProperty]
private bool isBusy;
private async Task OnItemInvoked(TypedEventHandler<object, object> args)
{
IsBusy = true;
//in real time i make some external API call here
await Task.Delay(TimeSpan.FromSeconds(10));
IsBusy = false;
}
}
1 ответ
Ты пропускаешьMode=OneWay
.
Режим по умолчаниюx:Bind
являетсяOneTime
(в отличие от режима по умолчаниюBinding
которыйOneWay
).Ссылка
<ProgressRing (...) IsActive="{x:Bind ViewModel.IsBusy, Mode=OneWay}"/>
<TextBlock (...) Visibility="{x:Bind ViewModel.IsBusy, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}"/>