【问题标题】:Xamarin ActivityIndicator Not WorkingXamarin ActivityIndi​​cator 不工作
【发布时间】:2020-10-23 02:40:22
【问题描述】:

我无法在 Xamarin.Forms 应用程序中显示活动指示器。我将 XAML 与 Code-behind 一起使用,它已绑定到视图模型。

在我看来所有设置都是正确的,当我单步执行代码时,我可以看到 IsBusy 属性被适当地设置为 True 和 False - 但实际的 ActivityIndi​​cator 根本不显示。

谁能看出我做错了什么?

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");
                }
            }
        }
    }
}

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.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="" Placeholder="Email address"/>
                                <Entry x:Name="password" Text="" IsPassword="true" Placeholder="Password"/>
                                <Button x:Name="loginButton" Text="Login" Clicked="OnLogin" 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>

LoginViewModel.cs

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

【问题讨论】:

    标签: c# xaml xamarin xamarin.forms


    【解决方案1】:

    这对我有用:

    private async void BtnLogin_OnClickedAsync(object sender, EventArgs e)
    {
        activityIndicator.IsRunning = true;
        await Task.Delay(1000); // This Line solved the problem with me
        await LoginMethod();
        activityIndicator.IsRunning = false;
    }
    

    【讨论】:

      【解决方案2】:

      [更新] 也许你应该分开责任。创建一个名为ViewModelBase 的类,它实现INotifyPropertyChanged,如下所示:

      public class ViewModelBase : INotifyPropertyChanged
      {
          bool isBusy;
      
          /// <summary>
          /// Gets or sets a value indicating whether this instance is busy.
          /// </summary>
          /// <value><c>true</c> if this instance is busy; otherwise, <c>false</c>.</value>
          public bool IsBusy
          {
              get { return isBusy; }
              set
              {
                  SetProperty(ref isBusy, value);
              }
          }
      
      
          /// <summary>
          /// Sets the property.
          /// </summary>
          /// <returns><c>true</c>, if property was set, <c>false</c> otherwise.</returns>
          /// <param name="backingStore">Backing store.</param>
          /// <param name="value">Value.</param>
          /// <param name="propertyName">Property name.</param>
          /// <param name="onChanged">On changed.</param>
          /// <typeparam name="T">The 1st type parameter.</typeparam>
          protected bool SetProperty<T>(
              ref T backingStore, T value,
              [CallerMemberName]string propertyName = "",
              Action onChanged = null)
          {
              if (EqualityComparer<T>.Default.Equals(backingStore, value))
                  return false;
      
              backingStore = value;
              onChanged?.Invoke();
              OnPropertyChanged(propertyName);
              return true;
          }
      
          /// <summary>
          /// Occurs when property changed.
          /// </summary>
          public event PropertyChangedEventHandler PropertyChanged;
          /// <summary>
          /// Raises the property changed event.
          /// </summary>
          /// <param name="propertyName">Property name.</param>
          protected void OnPropertyChanged([CallerMemberName]string propertyName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
      }
      

      然后创建另一个名为LoginViewModel 的类,它从ViewModelBase 扩展,如下所示:

      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");
                  }
              }
          }
      
      }
      

      你的看法是这样的:

      <?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 LoginCommand}" 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>
      

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

      我已经尝试过这个解决方案,并且效果很好......

      【讨论】:

      • 不,这不是这样做的。我认为这是因为我试图从代码隐藏中设置 viewmodel 属性。从我正在阅读的内容来看,这是不可能的,但是如果那是真的,我也看不到如何实现活动指示器!很困惑。
      • 也许你应该分开职责。创建一个名为ViewModelBase 的类,该类实现INotifyPropertyChanged,然后创建另一个从ViewModelBase 扩展的名为LoginViewModel 的类。请阅读更新
      • 谢谢,但我昨晚也试过了,但没有任何乐趣。我正在做的事情一定有什么根本性的错误。将回到视图上的绘图板。
      【解决方案3】:

      您没有通知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;
              }
          }
      }
      

      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.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;}
          }
      }
      

      【讨论】:

      • 哦,天哪,这是一个男生的错误...谢谢,当我回到我的电脑并让你知道时,我会尝试...
      • 不,不幸的是这仍然不起作用。同样的问题。单步执行我看到它设置了 IsBusy 标志,但屏幕不显示 ActivityIndi​​cator。至少不在模拟器中...
      • 似乎绑定有问题,因为我尝试在该表单上放置一个测试文本框以显示 IsBusy 值,但在整个过程中它只是说假
      • 我看到您在页面上指的是像 this.IsBusy = true; 这样的 IsBusy 属性...它不应该是像 this.BindingContext.IsBusy = true; 这样的东西?
      • 有趣的是,this.BindingContext.IsBusy 无效 - 就像 OnLogin 方法无法使用绑定上下文?
      【解决方案4】:

      我知道这是旧的,但也许这可以帮助某人。我也遇到了 ActivityIndi​​cator 没有显示的问题。

      为了让它正常工作,我做了一些事情。 在我的 ContentPage 上,它包含一个 ContentPage.Content 元素。删除此标签后,它开始使用下面的代码。

      我的代码隐藏上的绑定属性:

      public partial class Login : INotifyPropertyChanged
      {
          private bool _busy = true;
          public event PropertyChangedEventHandler PropertyChanged;
      
          public bool Busy
          {
              get { return _busy; }
              set
              {
                  _busy = value;
                  RaisePropertyChanged("Busy");
              }
          }
      
          private bool NotBusy => !Busy;
      
          public Login()
          {
              InitializeComponent();
              BindingContext = this;
              Busy = false;
          }
      
          private async void BtnLogin_OnClicked(object sender, EventArgs e)
          {
              Busy = true;
      
              await Task.Delay(120); // gives UI a chance to show the spinner
              // do async login here
              var cts = new CancellationTokenSource();
              var ct = cts.Token;
              var response = Task.Factory.StartNew(() => YourAuthenticationClass.YourLoginMethod(txtUserId.Text, txtPassword.Text).Result, ct);
              // check response, handle accordingly
          }
      
          private void RaisePropertyChanged(string propName)
          {
              System.Diagnostics.Debug.WriteLine("RaisePropertyChanged('" + propName + "')");
              PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
          }
      }
      

      ContentPage 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="MyApp.Login">
      <StackLayout Margin="10,10,10,0">
          <Image Source="mylogo.png"
                  HorizontalOptions="CenterAndExpand"></Image>
          <Entry x:Name="txtUserId"
                  Placeholder="Login Id"></Entry>
          <Entry x:Name="txtPassword"
                  Placeholder="Password"
                  IsPassword="True">
          </Entry>
          <Button Text="Login"
              Clicked="BtnLogin_OnClicked"
              IsEnabled="{Binding NotBusy}"></Button>
          <ActivityIndicator
                          IsRunning="{Binding Busy}"
                          IsVisible="{Binding Busy}"
                          IsEnabled="True"
                          AbsoluteLayout.LayoutFlags="PositionProportional"
                          AbsoluteLayout.LayoutBounds="0.5,0.5,-1,-1"
                          VerticalOptions="Center"
                          HorizontalOptions="Center">
              <ActivityIndicator.WidthRequest>
                  <OnPlatform x:TypeArguments="x:Double">
                      <On Platform="Android">100</On>
                  </OnPlatform>
              </ActivityIndicator.WidthRequest>
              <ActivityIndicator.Color>
                  <OnPlatform x:TypeArguments="Color">
                      <On Platform="Android">#ff0000</On>
                  </OnPlatform>
              </ActivityIndicator.Color>
          </ActivityIndicator>
      </StackLayout>
      </ContentPage>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-07-24
        • 1970-01-01
        • 1970-01-01
        • 2017-11-20
        • 1970-01-01
        • 2017-08-28
        • 1970-01-01
        相关资源
        最近更新 更多