2017-10-05 7 views
2

ViewModelにバインドされているような、かなり簡単なログインフォームがあります。ActivityIndi​​catorがViewModelにバインドされたXAMLに表示されない

すべてがアクティビティインジケータのほかにスムーズに機能します。私はそれが現れるようにあらゆる方法を試みました。

私が理解しているように、IsVisibleプロパティとIsRunningプロパティをtrueに設定すると、インジケータが表示されるはずです。私はこれらをboolプロパティにバインドしていますが、これはloginコマンド全体でtrue/falseに設定されています。

表示するには何が必要ですか?

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()); 
     } 
    } 
} 
+0

こんにちはMatthew。これは、viewModelで実行しているコードが、おそらく実行中に画面をフリーズしているからです。 'Login'メソッドのコードが終了すると同時にアクティビティインジケータが表示され、隠されています。 –

+0

メソッドを非同期に変更してみてください。それはトリックを行う必要があります –

+1

おかげでディエゴ - これを達成するための最良の方法についてのアドバイス? は、I)は、ボイドDoLogin( 'へ'ボイドログイン() '変化'、次いで が 'タスクログイン() { はTask.Runを待って非同期(async)保護された新しいメソッドを追加した(()=> DoLogin() ); } ' 私のコンストラクタで使用しているコマンドでは、非同期メソッドの戻り値の型が間違っていますか? –

答えて

2

変更しようあなたのViewModelメソッドLoginは次のようになります:

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); 
     } 
    }); 
} 
+1

はい、完璧です!もう一度あなたの助けをありがとう! –

関連する問題