C# Xamarin活动指示灯不工作

C# Xamarin活动指示灯不工作,c#,xaml,xamarin,xamarin.forms,C#,Xaml,Xamarin,Xamarin.forms,我在获取要在Xamarin.Forms应用程序中显示的活动指示器时遇到问题。我正在使用XAML和代码隐藏,它绑定到一个视图模型 在我看来,所有的设置都是正确的,当我逐步阅读代码时,我可以看到IsBusy属性被适当地设置为True和False,但实际的ActivityIndicator根本不显示 有人能看出我做错了什么吗 Login.Xaml.Cs using RestSharp; using System; using System.Collections.Generic; using Syst

我在获取要在Xamarin.Forms应用程序中显示的活动指示器时遇到问题。我正在使用XAML和代码隐藏,它绑定到一个视图模型

在我看来,所有的设置都是正确的,当我逐步阅读代码时,我可以看到IsBusy属性被适当地设置为True和False,但实际的ActivityIndicator根本不显示

有人能看出我做错了什么吗

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;
            ToolbarItems.Add(new ToolbarItem("New", "addperson.png", async () =>
            {
                await Navigation.PushAsync(new Register());
            }));

        }

        public string CleanResponse(string reason)
        {
            var str = reason;
            var charsToRemove = new string[] { "[", "]", "{", "}", "\"" };
            foreach (var c in charsToRemove)
            {
                str = str.Replace(c, string.Empty);
            }

            return str;
        }

        async void OnLogin(object sender, EventArgs e)
        {
            //Validations here
            if (email.Text == "")
            {
                await DisplayAlert("Validation Error", "You must enter an Email address", "OK");
                return;
            }
            else if (password.Text == "")
            {
                await DisplayAlert("Validation Error", "You must enter a Password", "OK");
                return;
            }
            //We are good to go
            else
            {
                this.IsBusy = true;
                string APIServer = Application.Current.Properties["APIServer"].ToString();
                var client = new RestClient(APIServer);
                var request = new RestRequest("api/account/sign-in", Method.POST);
                request.AddHeader("Content-type", "application/json");
                request.AddJsonBody(new
                                        {
                                            email = email.Text,
                                            password = password.Text
                                        }
                                    );

                var response = client.Execute(request) as RestResponse;

                this.IsBusy = false;
                //Valid response
                if (response.StatusCode.ToString() == "OK")
                {
                    var tokenobject = JsonConvert.DeserializeObject<TokenModel>(response.Content);
                    Application.Current.Properties["Token"] = tokenobject.Access_token;
                    string token = Application.Current.Properties["Token"].ToString();
                    App.Current.MainPage = new NavigationPage(new MainPage());

                }
                //Error response
                else
                {
                    var statuscode = response.StatusCode.ToString();
                    var content = response.Content;
                    var exception = response.ErrorException;
                    var error = response.ErrorMessage;
                    var statusdesc = response.StatusDescription;

                    await DisplayAlert("Login Failed", "Your login has failed. Please check your details and try again.", "OK");
                }
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace TechsportiseApp.ViewModels
{
    public class LoginViewModel : INotifyPropertyChanged
    {

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

                _isBusy = value;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

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

您没有通知
IsBusy
属性的更改

编辑代码:

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;
            ToolbarItems.Add(new ToolbarItem("New", "addperson.png", async () =>
            {
                await Navigation.PushAsync(new Register());
            }));

        }

        public string CleanResponse(string reason)
        {
            var str = reason;
            var charsToRemove = new string[] { "[", "]", "{", "}", "\"" };
            foreach (var c in charsToRemove)
            {
                str = str.Replace(c, string.Empty);
            }

            return str;
        }
    }
}
<?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.Padding>
        <OnPlatform x:TypeArguments="Thickness"
                    iOS="20, 40, 20, 20"
                    Android="20, 20, 20, 20"
                    WinPhone="20, 20, 20, 20" />
    </ContentPage.Padding>
    <ContentPage.Content>
        <AbsoluteLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
            <StackLayout VerticalOptions="FillAndExpand"
                         HorizontalOptions="FillAndExpand"
                         Orientation="Vertical"
                         AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1">
                <ScrollView  Orientation = "Vertical" VerticalOptions="StartAndExpand">
                    <StackLayout VerticalOptions="FillAndExpand"
                             HorizontalOptions="FillAndExpand"
                             Orientation="Vertical">
                        <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"/>
                        <Button x:Name="loginButton" Text="Login" Command="{Binding OnLoginCommand}" Style="{StaticResource Buttons}"/>
                    </StackLayout>
                </ScrollView>
            </StackLayout>
            <StackLayout IsVisible="{Binding IsBusy}" 
                         Padding="12"
                         AbsoluteLayout.LayoutFlags="PositionProportional"
                         AbsoluteLayout.LayoutBounds="0.5,0.5,1,1">

                <ActivityIndicator IsRunning="{Binding IsBusy}" Color ="#80000000"/>

                <Label Text="Loading..." HorizontalOptions="Center" TextColor="White"/>

            </StackLayout>
        </AbsoluteLayout>
        </ContentPage.Content>
</ContentPage>
using System.ComponentModel;
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.ViewModels
{
    public class LoginViewModel : INotifyPropertyChanged
    {

        public LoginViewModel()
        {
            OnLoginCommand = new Command(ExecuteOnLogin);
        }

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

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

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

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

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

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

        private async void ExecuteOnLogin()
        {
            //Validations here
            if (Email == "")
            {
                Device.BeginInvokeOnMainThread(() => App.Current.MainPage.DisplayAlert("Validation Error", "You must enter an Email address", "OK"));
                return;
            }
            else if (Password == "")
            {
                Device.BeginInvokeOnMainThread(() => App.Current.MainPage.DisplayAlert("Validation Error", "You must enter a Password", "OK"));
                return;
            }
            //We are good to go
            else
            {
                Device.BeginInvokeOnMainThread(() => IsBusy = true);
                string APIServer = Application.Current.Properties["APIServer"].ToString();
                var client = new RestClient(APIServer);
                var request = new RestRequest("api/account/sign-in", Method.POST);
                request.AddHeader("Content-type", "application/json");
                request.AddJsonBody(new
                                        {
                                            email = Email,
                                            password = Password
                                        }
                                    );

                var response = client.Execute(request) as RestResponse;

                Device.BeginInvokeOnMainThread(() => IsBusy = false);
                //Valid response
                if (response.StatusCode.ToString() == "OK")
                {
                    var tokenobject = JsonConvert.DeserializeObject<TokenModel>(response.Content);
                    Application.Current.Properties["Token"] = tokenobject.Access_token;
                    string token = Application.Current.Properties["Token"].ToString();
                    App.Current.MainPage = new NavigationPage(new MainPage());

                }
                //Error response
                else
                {
                    var statuscode = response.StatusCode.ToString();
                    var content = response.Content;
                    var exception = response.ErrorException;
                    var error = response.ErrorMessage;
                    var statusdesc = response.StatusDescription;

                    Device.BeginInvokeOnMainThread(() => App.Current.MainPage.DisplayAlert("Login Failed", "Your login has failed. Please check your details and try again.", "OK"));
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

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

        public Command OnLoginCommand {get;}
    }
}
Login.Xaml:

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;
            ToolbarItems.Add(new ToolbarItem("New", "addperson.png", async () =>
            {
                await Navigation.PushAsync(new Register());
            }));

        }

        public string CleanResponse(string reason)
        {
            var str = reason;
            var charsToRemove = new string[] { "[", "]", "{", "}", "\"" };
            foreach (var c in charsToRemove)
            {
                str = str.Replace(c, string.Empty);
            }

            return str;
        }
    }
}
<?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.Padding>
        <OnPlatform x:TypeArguments="Thickness"
                    iOS="20, 40, 20, 20"
                    Android="20, 20, 20, 20"
                    WinPhone="20, 20, 20, 20" />
    </ContentPage.Padding>
    <ContentPage.Content>
        <AbsoluteLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
            <StackLayout VerticalOptions="FillAndExpand"
                         HorizontalOptions="FillAndExpand"
                         Orientation="Vertical"
                         AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1">
                <ScrollView  Orientation = "Vertical" VerticalOptions="StartAndExpand">
                    <StackLayout VerticalOptions="FillAndExpand"
                             HorizontalOptions="FillAndExpand"
                             Orientation="Vertical">
                        <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"/>
                        <Button x:Name="loginButton" Text="Login" Command="{Binding OnLoginCommand}" Style="{StaticResource Buttons}"/>
                    </StackLayout>
                </ScrollView>
            </StackLayout>
            <StackLayout IsVisible="{Binding IsBusy}" 
                         Padding="12"
                         AbsoluteLayout.LayoutFlags="PositionProportional"
                         AbsoluteLayout.LayoutBounds="0.5,0.5,1,1">

                <ActivityIndicator IsRunning="{Binding IsBusy}" Color ="#80000000"/>

                <Label Text="Loading..." HorizontalOptions="Center" TextColor="White"/>

            </StackLayout>
        </AbsoluteLayout>
        </ContentPage.Content>
</ContentPage>
using System.ComponentModel;
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.ViewModels
{
    public class LoginViewModel : INotifyPropertyChanged
    {

        public LoginViewModel()
        {
            OnLoginCommand = new Command(ExecuteOnLogin);
        }

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

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

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

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

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

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

        private async void ExecuteOnLogin()
        {
            //Validations here
            if (Email == "")
            {
                Device.BeginInvokeOnMainThread(() => App.Current.MainPage.DisplayAlert("Validation Error", "You must enter an Email address", "OK"));
                return;
            }
            else if (Password == "")
            {
                Device.BeginInvokeOnMainThread(() => App.Current.MainPage.DisplayAlert("Validation Error", "You must enter a Password", "OK"));
                return;
            }
            //We are good to go
            else
            {
                Device.BeginInvokeOnMainThread(() => IsBusy = true);
                string APIServer = Application.Current.Properties["APIServer"].ToString();
                var client = new RestClient(APIServer);
                var request = new RestRequest("api/account/sign-in", Method.POST);
                request.AddHeader("Content-type", "application/json");
                request.AddJsonBody(new
                                        {
                                            email = Email,
                                            password = Password
                                        }
                                    );

                var response = client.Execute(request) as RestResponse;

                Device.BeginInvokeOnMainThread(() => IsBusy = false);
                //Valid response
                if (response.StatusCode.ToString() == "OK")
                {
                    var tokenobject = JsonConvert.DeserializeObject<TokenModel>(response.Content);
                    Application.Current.Properties["Token"] = tokenobject.Access_token;
                    string token = Application.Current.Properties["Token"].ToString();
                    App.Current.MainPage = new NavigationPage(new MainPage());

                }
                //Error response
                else
                {
                    var statuscode = response.StatusCode.ToString();
                    var content = response.Content;
                    var exception = response.ErrorException;
                    var error = response.ErrorMessage;
                    var statusdesc = response.StatusDescription;

                    Device.BeginInvokeOnMainThread(() => App.Current.MainPage.DisplayAlert("Login Failed", "Your login has failed. Please check your details and try again.", "OK"));
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

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

        public Command OnLoginCommand {get;}
    }
}

查看模型:

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;
            ToolbarItems.Add(new ToolbarItem("New", "addperson.png", async () =>
            {
                await Navigation.PushAsync(new Register());
            }));

        }

        public string CleanResponse(string reason)
        {
            var str = reason;
            var charsToRemove = new string[] { "[", "]", "{", "}", "\"" };
            foreach (var c in charsToRemove)
            {
                str = str.Replace(c, string.Empty);
            }

            return str;
        }
    }
}
<?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.Padding>
        <OnPlatform x:TypeArguments="Thickness"
                    iOS="20, 40, 20, 20"
                    Android="20, 20, 20, 20"
                    WinPhone="20, 20, 20, 20" />
    </ContentPage.Padding>
    <ContentPage.Content>
        <AbsoluteLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
            <StackLayout VerticalOptions="FillAndExpand"
                         HorizontalOptions="FillAndExpand"
                         Orientation="Vertical"
                         AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1">
                <ScrollView  Orientation = "Vertical" VerticalOptions="StartAndExpand">
                    <StackLayout VerticalOptions="FillAndExpand"
                             HorizontalOptions="FillAndExpand"
                             Orientation="Vertical">
                        <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"/>
                        <Button x:Name="loginButton" Text="Login" Command="{Binding OnLoginCommand}" Style="{StaticResource Buttons}"/>
                    </StackLayout>
                </ScrollView>
            </StackLayout>
            <StackLayout IsVisible="{Binding IsBusy}" 
                         Padding="12"
                         AbsoluteLayout.LayoutFlags="PositionProportional"
                         AbsoluteLayout.LayoutBounds="0.5,0.5,1,1">

                <ActivityIndicator IsRunning="{Binding IsBusy}" Color ="#80000000"/>

                <Label Text="Loading..." HorizontalOptions="Center" TextColor="White"/>

            </StackLayout>
        </AbsoluteLayout>
        </ContentPage.Content>
</ContentPage>
using System.ComponentModel;
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.ViewModels
{
    public class LoginViewModel : INotifyPropertyChanged
    {

        public LoginViewModel()
        {
            OnLoginCommand = new Command(ExecuteOnLogin);
        }

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

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

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

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

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

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

        private async void ExecuteOnLogin()
        {
            //Validations here
            if (Email == "")
            {
                Device.BeginInvokeOnMainThread(() => App.Current.MainPage.DisplayAlert("Validation Error", "You must enter an Email address", "OK"));
                return;
            }
            else if (Password == "")
            {
                Device.BeginInvokeOnMainThread(() => App.Current.MainPage.DisplayAlert("Validation Error", "You must enter a Password", "OK"));
                return;
            }
            //We are good to go
            else
            {
                Device.BeginInvokeOnMainThread(() => IsBusy = true);
                string APIServer = Application.Current.Properties["APIServer"].ToString();
                var client = new RestClient(APIServer);
                var request = new RestRequest("api/account/sign-in", Method.POST);
                request.AddHeader("Content-type", "application/json");
                request.AddJsonBody(new
                                        {
                                            email = Email,
                                            password = Password
                                        }
                                    );

                var response = client.Execute(request) as RestResponse;

                Device.BeginInvokeOnMainThread(() => IsBusy = false);
                //Valid response
                if (response.StatusCode.ToString() == "OK")
                {
                    var tokenobject = JsonConvert.DeserializeObject<TokenModel>(response.Content);
                    Application.Current.Properties["Token"] = tokenobject.Access_token;
                    string token = Application.Current.Properties["Token"].ToString();
                    App.Current.MainPage = new NavigationPage(new MainPage());

                }
                //Error response
                else
                {
                    var statuscode = response.StatusCode.ToString();
                    var content = response.Content;
                    var exception = response.ErrorException;
                    var error = response.ErrorMessage;
                    var statusdesc = response.StatusDescription;

                    Device.BeginInvokeOnMainThread(() => App.Current.MainPage.DisplayAlert("Login Failed", "Your login has failed. Please check your details and try again.", "OK"));
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

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

        public Command OnLoginCommand {get;}
    }
}
使用System.ComponentModel;
使用RestSharp;
使用制度;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用TechsportiseApp.Views;
使用Xamarin.Forms;
使用Xamarin.Forms.Xaml;
使用TechsportiseApp.API;
使用TechsportiseApp.ViewModels;
使用TechsportiseApp.Models;
使用Newtonsoft.Json;
命名空间TechsportiseApp.ViewModels
{
公共类LoginView模型:INotifyPropertyChanged
{
公共登录视图模型()
{
OnLoginCommand=新命令(ExecuteOnLogin);
}
私人厕所很忙;
公共图书馆很忙
{
获取{return\u isBusy;}
设置
{
如果(_isBusy==值)
返回;
_isBusy=值;
OnPropertyChanged(“IsBusy”);
}
}
私人字符串\u电子邮件;
公共字符串电子邮件
{
获取{return\u email;}
设置
{
如果(_email==值)
返回;
_电子邮件=价值;
OnPropertyChanged(“电子邮件”);
}
}
私人密码;
公共bool密码
{
获取{return\u password;}
设置
{
如果(_password==值)
返回;
_密码=值;
OnPropertyChanged(“密码”);
}
}
私有异步void ExecuteOnLogin()
{
//这里的验证
如果(电子邮件==“”)
{
Device.beginInvokeMainThread(()=>App.Current.MainPage.DisplayAlert(“验证错误”,“您必须输入电子邮件地址”,“确定”));
返回;
}
else if(密码==“”)
{
Device.beginInvokeMainThread(()=>App.Current.MainPage.DisplayAlert(“验证错误”,“必须输入密码”,“确定”));
返回;
}
//我们可以走了
其他的
{
Device.beginInvokeMainThread(()=>IsBusy=true);
字符串APIServer=Application.Current.Properties[“APIServer”].ToString();
var client=新的RestClient(APIServer);
var请求=新的重新请求(“api/帐户/登录”,Method.POST);
AddHeader(“内容类型”、“应用程序/json”);
request.AddJsonBody(新的
{
电子邮件=电子邮件,
密码=密码
}
);
var response=client.Execute(request)as response;
Device.beginInvokeMainThread(()=>IsBusy=false);
//有效响应
if(response.StatusCode.ToString()=“OK”)
{
var tokenobject=JsonConvert.DeserializeObject(response.Content);
Application.Current.Properties[“Token”]=tokenobject.Access\u Token;
字符串标记=Application.Current.Properties[“token”].ToString();
App.Current.MainPage=新导航页面(新主页());
}
//错误响应
其他的
{
var statuscode=response.statuscode.ToString();
var content=response.content;
var exception=response.ErrorException;
var error=response.ErrorMessage;
var statusdesc=response.StatusDescription;
Device.beginInvokeMainThread(()=>App.Current.MainPage.DisplayAlert(“登录失败”,“您的登录失败。请检查您的详细信息,然后重试。”,“确定”));
}
}
}
公共事件属性更改事件处理程序属性更改;
受保护的虚拟void OnPropertyChanged(字符串propertyName)
{
var changed=Property changed;
如果(已更改!=null)
{
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
公共命令OnLoginCommand{get;}
}
}
[更新]
也许你应该把责任分开。创建一个名为
ViewModelBase
的类,该类实现了
INotifyPropertyChanged
,如下所示:

public class LoginViewModel : ViewModelBase
{
    public ICommand LoginCommand { get; set; }

    #region Properties
    private string _email;

    public string Email
    {
        get { return _email; }
        set { SetProperty(ref _email, value); }
    }

    private string _password;

    public string Password
    {
        get { return _password; }
        set { SetProperty(ref _password, value); }
    }

    #endregion

    public LoginViewModel()
    {
        LoginCommand = new Command(Login);
    }

    public string CleanResponse(string reason)
    {
        var str = reason;
        var charsToRemove = new string[] { "[", "]", "{", "}", "\"" };
        foreach (var c in charsToRemove)
        {
            str = str.Replace(c, string.Empty);
        }

        return str;
    }

    private async void Login()
    {
       //Validations here
        if (Email == "")
        {
            await DisplayAlert("Validation Error", "You must enter an Email address", "OK");
            return;
        }
        else if (Password == "")
        {
            await DisplayAlert("Validation Error", "You must enter a Password", "OK");
            return;
        }
        //We are good to go
        else
        {
            IsBusy = true;
            string APIServer = Application.Current.Properties["APIServer"].ToString();
            var client = new RestClient(APIServer);
            var request = new RestRequest("api/account/sign-in", Method.POST);
            request.AddHeader("Content-type", "application/json");
            request.AddJsonBody(new
                                    {
                                        email = Email,
                                        password = Password                                        }
                                );

            var response = client.Execute(request) as RestResponse;

            IsBusy = false;
            //Valid response
            if (response.StatusCode.ToString() == "OK")
            {
                var tokenobject = JsonConvert.DeserializeObject<TokenModel>(response.Content);
                Application.Current.Properties["Token"] = tokenobject.Access_token;
                string token = Application.Current.Properties["Token"].ToString();
                App.Current.MainPage = new NavigationPage(new MainPage());

            }
            //Error response
            else
            {
                var statuscode = response.StatusCode.ToString();
                var content = response.Content;
                var exception = response.ErrorException;
                var error = response.ErrorMessage;
                var statusdesc = response.StatusDescription;

                await DisplayAlert("Login Failed", "Your login has failed. Please check your details and try again.", "OK");
            }
        }
    }

}
公共类ViewModelBase:INotifyPropertyChanged
{
布尔很忙;
/// 
///获取或设置一个值,该值指示此实例是否正忙。
/// 
///如果此实例正忙,则为true;否则为false。
公共图书馆很忙
{
获取{return isBusy;}
设置
{
刚毛