Kontrolka oczekiwania

0

Witam.
Zaczynam swoją przygodę z Xamarinem dlatego pytanie możedla niektórych będzie śmieszne.
Mianowicie:
Na stronie PopupPage w Xamarinie pod zdarzeniem przycisku wywołuję funkcję, która działa długo i oczekuję od niej zwrotu wartości.
Chciałbym pokazać użytkownikowi, że program działa a nie się zawiesił. Znalazłem kontrolkę ActivityIndicator lecz niestety nie chce ona mi się pokazać.
Zauważyłem, że aplikacja zawiesza mi się do momentu aż wywoływana funkcja skończy swoje działanie (klawisz jest wciśnięty, klawiatura ekranowa zostawia swój ślad na ekranie).
Do tej pory pracowałem w WPF i tam można było wymusić z kodu odświeżenie okna (wywołać główny wątek na chwilę aby przerysował kontolki).
W Xamarinie nie mogę znaleźć czegoś takiego. Jest co prawda metoda App.DoEvents() ale w moim projekcie nie widzę jej.
Czy jest jakiś sposób aby rozwiązać mój problem?

Próbowałem już wywołać ta metodę w BackgroundWorker'ze, w metodzie asynchronicznej, gdzie w głównym wątku czekam na flagę zakończenia tej metody ale niestety nic z tego nie działa.
Co robię źle?

Poniżej kod strony:

<pages:PopupPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup"
                 xmlns:animations="clr-namespace:Rg.Plugins.Popup.Animations;assembly=Rg.Plugins.Popup" xmlns:popup="clr-namespace:SMM.ViewModel.Popup" x:DataType="popup:AfterAddingViewModel"
                 xmlns:viewmodel="clr-namespace:SMM.ViewModel"
                 x:Name="thisPage"
                 x:Class="SMM.Pages.TableSale.Popup.CustomerAddEditDialog">

    <pages:PopupPage.Animation>
        <animations:ScaleAnimation
            PositionIn="Center"
            PositionOut="Center"
            ScaleIn="1"
            ScaleOut="0.8"
            DurationIn="300"
            DurationOut="200"
            EasingIn="SinOut"
            EasingOut="SinIn"/>
    </pages:PopupPage.Animation>

    <pages:PopupPage.Resources>
        <ResourceDictionary>
            <Style x:Key="labelName" TargetType="{x:Type Label}">
                <Setter Property="TextColor" Value="{DynamicResource ColorPrimaryTextColor}"/>
                <Setter Property="FontSize" Value="Caption"/>
                <Setter Property="Margin" Value="4,4,4,16"/>
                <Setter Property="HorizontalOptions" Value="StartAndExpand"/>
                <Setter Property="VerticalOptions" Value="EndAndExpand"/>
            </Style>
            <Style x:Key="entryStyle" TargetType="{x:Type Entry}">
                <Setter Property="TextColor" Value="{DynamicResource ColorPrimaryTextColor}"/>
                <Setter Property="FontSize" Value="Body"/>
                <Setter Property="Margin" Value="4"/>
                <Setter Property="HorizontalOptions" Value="FillAndExpand"/>
                <Setter Property="ClearButtonVisibility" Value="WhileEditing"/>
                <Setter Property="IsSpellCheckEnabled" Value="false"/>
            </Style>
        </ResourceDictionary>
    </pages:PopupPage.Resources>

        <StackLayout VerticalOptions="Center" Padding="25,0,25,0" HorizontalOptions="FillAndExpand" x:DataType="viewmodel:DisplayAlertViewModel" BackgroundColor="White">
            <Frame CornerRadius="20" BackgroundColor="{DynamicResource NoteBackground}">
                <Grid x:Name="mainGrid">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>

                    <Label Grid.Row="0" Grid.Column="0" Text="{DynamicResource txtKlient}" FontSize="Title" Padding="0,10,0,10" HorizontalOptions="Start"
                       TextColor="{DynamicResource ColorPrimaryTextColor}"/>
                    <Label Grid.Row="0" Grid.Column="1" Text="{DynamicResource txtKlientZnaleziony}" FontSize="Title" Padding="0,10,0,10" HorizontalOptions="End"
                       TextColor="{DynamicResource ColorPrimaryTSelectedextColor}"
                       IsVisible="{Binding Source={x:Reference thisPage}, Path=IsCustomerFinded, Mode=OneWay}"/>

                    <ScrollView Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>

                            <Label Grid.Row="1" Grid.Column="0" Text="{DynamicResource txtKlientNIP}" Style="{StaticResource labelName}"/>
                            <Entry Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3" Text="{Binding Customer.NIP}" Style="{StaticResource entryStyle}"/>

                            <Label Grid.Row="2" Grid.Column="0" Text="{DynamicResource txtKlientFirma}" Style="{StaticResource labelName}"/>
                            <Entry Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="3" Text="{Binding Customer.FirmName}" Style="{StaticResource entryStyle}" MaxLength="100"/>

                            <Label Grid.Row="3" Grid.Column="0" Text="{DynamicResource txtKlientNazwisko}" Style="{StaticResource labelName}"/>
                            <Entry Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="3" Text="{Binding Customer.Name}" Style="{StaticResource entryStyle}" MaxLength="50"/>

                            <Label Grid.Row="4" Grid.Column="0" Text="{DynamicResource txtKlientImiona}" Style="{StaticResource labelName}"/>
                            <Entry Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="3" Text="{Binding Customer.FirstName}" Style="{StaticResource entryStyle}" MaxLength="50"/>

                            <Label Grid.Row="5" Grid.Column="0" Text="{DynamicResource txtKlientUlica}" Style="{StaticResource labelName}"/>
                            <Entry Grid.Row="5" Grid.Column="1" Grid.ColumnSpan="3" Text="{Binding Customer.Street}" Style="{StaticResource entryStyle}" MaxLength="50"/>

                            <Label Grid.Row="6" Grid.Column="0" Text="{DynamicResource txtKlientNrDomu}" Style="{StaticResource labelName}"/>
                            <Entry Grid.Row="6" Grid.Column="1" Text="{Binding Customer.PossesionNr}" Style="{StaticResource entryStyle}" MaxLength="20"/>
                            <Label Grid.Row="6" Grid.Column="2" Text="{DynamicResource txtKlientNrLokalu}" Style="{StaticResource labelName}"/>
                            <Entry Grid.Row="6" Grid.Column="3" Text="{Binding Customer.LocalNr}" Style="{StaticResource entryStyle}" MaxLength="10"/>

                            <Label Grid.Row="7" Grid.Column="0" Text="{DynamicResource txtKlientMiasto}" Style="{StaticResource labelName}"/>
                            <Entry Grid.Row="7" Grid.Column="1" Grid.ColumnSpan="3" Text="{Binding Customer.City}" Style="{StaticResource entryStyle}" MaxLength="50"/>

                            <Label Grid.Row="8" Grid.Column="0" Text="{DynamicResource txtKlientKodPocztowy}" Style="{StaticResource labelName}"/>
                            <Entry Grid.Row="8" Grid.Column="1" Grid.ColumnSpan="3" Text="{Binding Customer.PostCode}" Style="{StaticResource entryStyle}" MaxLength="10"/>

                        </Grid>
                    </ScrollView>

                    <Button Grid.Row="2" Grid.Column="0" Style="{StaticResource ButtonCancelStyle}" Text="{DynamicResource txtKlientGUS}" Clicked="btnGUS_Clicked" />
                    <Button Grid.Row="2" Grid.Column="1" Style="{StaticResource ButtonOkStyle}" Text="{DynamicResource Search}" Clicked="btnSearch_Clicked" />

                    <Button Grid.Row="3" Grid.Column="0" Style="{StaticResource ButtonCancelStyle}" Command="{Binding CancelCommand}"/>
                    <Button Grid.Row="3" Grid.Column="1" Style="{StaticResource ButtonOkStyle}" Command="{Binding OkCommand}" x:Name="btnOk"/>

                    <ActivityIndicator Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Grid.RowSpan="4" Color="Orange"
                                   HorizontalOptions="Center" VerticalOptions="Center"
                                   IsVisible="{Binding Source={x:Reference thisPage}, Path=IsBusy, Mode=OneWay}"
                                   IsRunning="{Binding Source={x:Reference thisPage}, Path=IsBusy, Mode=OneWay}"
                                   IsEnabled="{Binding Source={x:Reference thisPage}, Path=IsBusy, Mode=OneWay}"/>
                </Grid>
            </Frame>
        </StackLayout>

</pages:PopupPage>

I kod klawisza:

private async void btnGUS_Clicked(object sender, EventArgs e)
{
    try
    {
        DAL.LocalDB.Checks.Customer customer = ((DisplayAlertViewModel)BindingContext).Customer;

        DAL.Services.GUSCustomer gus = null;
        try
        {
            Device.BeginInvokeOnMainThread(() =>
            {
                ((DisplayAlertViewModel)BindingContext).IsBusy = true;
                IsBusy = true;
            });

            gus = DAL.Services.GUSReader.Instance.FindCustomer(DAL.LocalDB.ConfigValues.Instance.KluczUzytkownikaSerwisuGUS, customer.NIP, DAL.Services.GUSReader.SearchType.NIP, false);

        }
        finally
        {
            Device.BeginInvokeOnMainThread(() =>
            {
                ((DisplayAlertViewModel)BindingContext).IsBusy = false;
                IsBusy = false;
            });
        }
        
        if (gus == null)
        {
            await DisplayAlert(string.Empty, LanguageManager.GetText("txtKlientNieZnalezionoWGUS"), "OK");
            return;
        }

        ((DisplayAlertViewModel)BindingContext).Customer = new Customer(gus);
        IsCustomerFinded = true;
    }
    catch (Exception exp)
    {
        ExceptionHandling.ExceptionHandler.Instance.Handle("Błąd pobierania danych klienta z bazy GUS", exp);
    }
}
1

Rozumiem, że DAL.Services.GUSReader.Instance.FindCustomer() to ta metoda, która długo trwa?

Próbowałeś prostego:

await Task.Run(() =>
{
    LongBlockingMethod();
});

(i ogólnie nie wchodziłbym już w Xamarin.Forms, bo mamy MAUI, który jest jego następcą)

0
Ktos napisał(a):

Rozumiem, że DAL.Services.GUSReader.Instance.FindCustomer() to ta metoda, która długo trwa?

Próbowałeś prostego:

await Task.Run(() =>
{
    LongBlockingMethod();
});

(i ogólnie nie wchodziłbym już w Xamarin.Forms, bo mamy MAUI, który jest jego następcą)

Dzięki za podpowiedź.
Pomogło dopiero gdy wrzuciłem wywołanie tej metody do procedury asynchronicznej bez czekania na jej zakończenie i przekazałem sterownie do głównego wątku. O to mi właśnie chodziło.

1 użytkowników online, w tym zalogowanych: 0, gości: 1