2 votes

ActivityIndicator ne s'affiche pas dans le XAML lié à ViewModel

J'ai un formulaire de connexion assez simple en apparence, que j'ai lié à un viewmodel.

Tout fonctionne à merveille, à part l'indicateur d'activité. J'ai essayé toutes sortes de choses pour le faire apparaître.

Si je comprends bien, les propriétés IsVisible et IsRunning, lorsqu'elles sont définies sur true, devraient faire apparaître l'indicateur. Je les ai liées à une propriété bool qui reçoit la valeur true/false tout au long de la commande de connexion.

Que dois-je faire pour qu'il s'affiche ?

Login.xaml

<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="TechsportiseApp.Views.Login">
    <ContentPage.ToolbarItems>
        <ToolbarItem Name="Register" Order="Primary" Icon="addperson.png" Text="Register" Priority="0" Command="{Binding RegisterCommand}" />
        <ToolbarItem Name="Help" Order="Primary" Icon="help.png" Text="Help" Priority="1" Command="{Binding HelpCommand}" />
    </ContentPage.ToolbarItems>
    <ContentPage.Content>
        <RelativeLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
            <StackLayout HorizontalOptions="FillAndExpand">
                <StackLayout HorizontalOptions="FillAndExpand" BackgroundColor="Red" Padding="2" IsVisible="{Binding IsOffline}">
                    <Label Text="OFFLINE" BackgroundColor="Red" TextColor="White" FontAttributes="Bold" FontSize="Small" HorizontalOptions="FillAndExpand" HorizontalTextAlignment="Center" />
                </StackLayout>
                <StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Orientation="Vertical">
                    <ScrollView Orientation="Vertical" VerticalOptions="StartAndExpand">
                        <StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Orientation="Vertical" Margin="10">
                            <Image Source="splash.png" HorizontalOptions="Center" />
                            <Label Text="Race Director" FontAttributes="Bold" FontSize="Large" HorizontalTextAlignment="Center" HorizontalOptions="CenterAndExpand" />
                            <Label Text="by Techsportise" HorizontalTextAlignment="Center" HorizontalOptions="CenterAndExpand" />
                            <BoxView HeightRequest="20" HorizontalOptions="FillAndExpand" />
                            <Entry x:Name="email" Text="{Binding Email}" Placeholder="Email address" />
                            <Entry x:Name="password" Text="{Binding Password}" IsPassword="true" Placeholder="Password" />
                            <StackLayout Padding="3" Orientation="Horizontal">
                                <Label Style="{StaticResource EntryFormLabels}" Text="REMEMBER ME" FontSize="Small" HorizontalOptions="StartAndExpand" VerticalTextAlignment="Center" />
                                <Switch IsToggled="{Binding RememberMe}" HorizontalOptions="End" />
                            </StackLayout>
                            <Button x:Name="loginButton" Text="Login" Command="{Binding LoginCommand}" Style="{StaticResource Buttons}" />
                            <ActivityIndicator IsVisible="{Binding IsBusy}" IsRunning="{Binding IsBusy}" Color="#80000000" />
                            <Label Text="{Binding ValidationError}" HorizontalTextAlignment="Center" HorizontalOptions="CenterAndExpand" TextColor="Red" FontSize="Small" IsVisible="{Binding Invalid}" />
                        </StackLayout>
                    </ScrollView>
                </StackLayout>
            </StackLayout>
            <ActivityIndicator IsVisible="{Binding IsBusy}"
                               IsRunning="{Binding IsBusy}"
                               Color="Black"
                               VerticalOptions="CenterAndExpand"
                               HorizontalOptions="CenterAndExpand"
                               RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent,
                                        Property=Width,
                                        Factor=1}"
                               RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent,
                                        Property=Height,
                                        Factor=1}" />
        </RelativeLayout>
    </ContentPage.Content>
</ContentPage>

Login.xaml.cs

using RestSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TechsportiseApp.Views;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using TechsportiseApp.API;
using TechsportiseApp.ViewModels;
using TechsportiseApp.Models;
using Newtonsoft.Json;

namespace TechsportiseApp.Views
{
    public partial class Login : ContentPage
    {
        public Login ()
        {
            InitializeComponent ();
            var viewModel = new LoginViewModel();
            BindingContext = viewModel;
        }

        public Login(string email)
        {
            InitializeComponent();
            var viewModel = new LoginViewModel(email);
            BindingContext = viewModel;
        }
    }
}

Loginviewmodel

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Input;
using TechsportiseApp.API;
using TechsportiseApp.Helpers;
using TechsportiseApp.Models;
using TechsportiseApp.Views;
using Xamarin.Forms;

namespace TechsportiseApp.ViewModels
{
    public class LoginViewModel : INotifyPropertyChanged
    {
        public INavigation Navigation { get; set; }
        public ICommand LoginCommand { get; set; }
        public ICommand HelpCommand { get; set; }
        public ICommand RegisterCommand { get; set; }
        public LoginViewModel()
        {
            LoginCommand = new Command(Login);
            HelpCommand = new Command(Help);
            RegisterCommand = new Command(Register);
            Invalid = false;
        }

        public LoginViewModel(string email)
        {
            LoginCommand = new Command(Login);
            HelpCommand = new Command(Help);
            RegisterCommand = new Command(Register);
            Invalid = true;
            ValidationError = "the account for " + email + " has been created.";
        }

        private bool _isBusy;
        public bool IsBusy
        {
            get { return _isBusy; }
            set
            {
                if (_isBusy == value)
                    return;

                _isBusy = value;
                OnPropertyChanged("IsBusy");
            }
        }

        private bool _isOffline;
        public bool IsOffline
        {
            get
            {
                _isOffline = !GlobalFunctions.CheckForInternetConnection();
                return _isOffline;
            }
        }

        private bool _rememberMe;
        public bool RememberMe
        {
            get
            {
                if (Application.Current.Properties.ContainsKey("IsRemembered"))
                {
                    _rememberMe = bool.Parse(Application.Current.Properties["IsRemembered"].ToString());
                    return _rememberMe;

                }
                else
                {
                    return _rememberMe;
                }
            }
            set
            {
                if (_rememberMe == value)
                    return;

                _rememberMe = value;
                Application.Current.Properties["IsRemembered"] = _rememberMe;
                OnPropertyChanged("RememberMe");
            }
        }

        private bool _invalid;
        public bool Invalid
        {
            get { return _invalid; }
            set
            {
                if (_invalid == value)
                    return;

                _invalid = value;
                OnPropertyChanged("Invalid");
            }
        }

        private string _validationError;
        public string ValidationError
        {
            get { return _validationError; }
            set
            {
                if (_validationError == value)
                    return;

                _validationError = value;
                OnPropertyChanged("ValidationError");
            }
        }

        private string _email;
        public string Email
        {
            get { return _email; }
            set
            {
                if (_email == value)
                    return;

                _email = value;
                OnPropertyChanged("Email");
            }
        }

        private string _password;
        public string Password
        {
            get { return _password; }
            set
            {
                if (_password == value)
                    return;

                _password = value;
                OnPropertyChanged("Password");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            var changed = PropertyChanged;
            if (changed != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        void Login()
        {
            IsBusy = true;
            var isvalidemail = GlobalFunctions.IsValidEmail(Email);
            var IsThereConnection = GlobalFunctions.CheckForInternetConnection();

            if (IsThereConnection == false)
            {
                Invalid = true;
                ValidationError = "You cannot login whilst you are offline";
                IsBusy = false;
                return;
            }
            else if (Email == "")
            {
                Invalid = true;
                ValidationError = "You must enter an email address";
                IsBusy = false;
                return;
            }
            else if (Password == "")
            {
                Invalid = true;
                ValidationError = "You must enter a password";
                IsBusy = false;
                return;
            }
            else if (isvalidemail == false)
            {
                Invalid = true;
                ValidationError = "You must enter a valid email address";
                IsBusy = false;
                return;
            }
            //We are good to go
            else
            {
                IsBusy = true;
                var LoginStatus = AccountsAPI.Login(Email, Password);
                if (LoginStatus.Code == "OK")
                {
                    var tokenobject = JsonConvert.DeserializeObject<TokenModel>(LoginStatus.Content);
                    Application.Current.Properties["Token"] = tokenobject.Access_token;
                    Application.Current.Properties["IsRemembered"] = RememberMe;
                    string token = Application.Current.Properties["Token"].ToString();
                    if ((bool)Application.Current.Properties["ShowHelpOnStartup"] == true)
                    {
                        App.Current.MainPage = new StartupHelp(true);
                    }
                    else
                    {
                        App.Current.MainPage = new MainMenuMasterDetail();
                    }

                }
                //Error response
                else
                {
                    IsBusy = false;
                    Invalid = true;
                    ValidationError = "Your login has failed. Please check your details and try again.";
                }
            }
        }

        void Register()
        {
            Xamarin.Forms.Application.Current.MainPage.Navigation.PushAsync(new Register());
        }

        void Help()
        {
            Xamarin.Forms.Application.Current.MainPage.Navigation.PushAsync(new LoginHelp());
        }
    }
}

2voto

Diego Rafael Souza Points 3371

Essayez de modifier votre méthode ViewModel Login pour être comme ça :

private void Login()
{
    Task.Run(() => 
    {
        try
        {
            Device.BeginInvokeOnMainThread(() => IsBusy = true);
            var isvalidemail = GlobalFunctions.IsValidEmail(Email);
            var IsThereConnection = GlobalFunctions.CheckForInternetConnection();

            if (IsThereConnection == false)
                throw new Exception("You cannot login whilst you are offline");
            else if (Email == "")
                throw new Exception("You must enter an email address");
            else if (Password == "")
                throw new Exception("You must enter a password");
            else if (isvalidemail == false)
                throw new Exception("You must enter a valid email address");
            //We are good to go
            else
            {
                var LoginStatus = AccountsAPI.Login(Email, Password);
                if (LoginStatus.Code == "OK")
                {
                    var tokenobject = JsonConvert.DeserializeObject<TokenModel>(LoginStatus.Content);
                    Application.Current.Properties["Token"] = tokenobject.Access_token;
                    Application.Current.Properties["IsRemembered"] = RememberMe;
                    string token = Application.Current.Properties["Token"].ToString();
                    if ((bool)Application.Current.Properties["ShowHelpOnStartup"] == true)
                        Device.BeginInvokeOnMainThread(() => App.Current.MainPage = new StartupHelp(true));
                    else
                        Device.BeginInvokeOnMainThread(() => App.Current.MainPage = new MainMenuMasterDetail());
                }
                //Error response
                else
                    throw new Exception("Your login has failed. Please check your details and try again.");         
            }
        }
        catch(Exception ex)
        {

            Device.BeginInvokeOnMainThread(() => 
            {
                ValidationError = ex.Message;
                Invalid = true;
            });
        }
        finally
        {
            Device.BeginInvokeOnMainThread(() => IsBusy = true);
        }
    });
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X