【问题标题】:Activity Indicator not displaying until all code has executed在所有代码执行之前,活动指示器不显示
【发布时间】:2019-12-29 14:05:58
【问题描述】:

基本上,我有一个活动指示器,直到方法中的所有其他代码都已执行后才会显示。我已经查看并且 IsBusy 属性在代码端(登录页面)和 xaml 绑定(登录 xaml)都设置为 true,所以我知道正确的值至少会被传递。

我很确定我已经正确设置了一切,只要 async / await 不会锁定任何东西。

我有一个所有视图模型都使用的 BaseViewModel 类。这是 IsBusy 的代码:

bool isBusy = false;
    public bool IsBusy
    {
        get { return isBusy; }
        set { SetProperty(ref isBusy, value); }
    }

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

这是我用于登录页面的 XAML。活动指示器放置在 Content Page 标记内的单个 Stack Layout 中:

<ActivityIndicator IsRunning="{Binding IsBusy}"
                     IsVisible="{Binding IsBusy}"
                      HeightRequest="40"
                      VerticalOptions="CenterAndExpand"
                      HorizontalOptions="CenterAndExpand">
        <ActivityIndicator.WidthRequest>
            <OnPlatform x:TypeArguments="x:Double" iOS="100" Android="100" />
        </ActivityIndicator.WidthRequest>
        <ActivityIndicator.Color>
            <OnPlatform x:TypeArguments="Color"
                  iOS="#2499CE" />
        </ActivityIndicator.Color>
    </ActivityIndicator>

这里是 LoginPageViewModel 代码。如果我正确理解这一点,则指示器应在第一行设置为 true 后立即显示,然后在 API 调用完成且用户未通过身份验证后消失。

public async void OnLogin()
    {
        IsBusy = true;

        var isAuthenticated = await LoginPageValidation.IsAuthenticated(email, password);
        if (!isAuthenticated )
        {
            IsBusy = false;
            IsForgotPasswordLabelVisible = true;
            DisplayUserAndPasswordMismatchPrompt();
            return;
        }
    }

我确定问题很小,但我只是没有看到它。

编辑:添加 IsAuthenticated 方法

IsAuthenticated

public static async Task<bool> IsAuthenticated(string email, string password)
    {
        var isAuthenticated = false;
        try
        {
            var payload = $"{{\n\t\"Email\":\"{email}\",\n\t\"Password\":\"{password}\"\n}}";
            var response = await LoginApi.Authenticate(payload);
            isAuthenticated = bool.Parse(response["isAuthenticated"].ToString());
        }
        catch (Exception e)
        {
            // log stuff here
        }

        return isAuthenticated;
    }

验证 API 调用:

public static async Task<JObject> Authenticate(string payloadBody)
    {
        IRestResponse response = null;
        try
        {
            var client = new RestClient($"{url}/authenticate");
            var request = new RestRequest(Method.POST);
            request.AddHeader("Content-Type", "application/json");
            request.AddParameter("undefined", payloadBody, ParameterType.RequestBody);
            response = client.Execute(request);
        } catch (Exception e)
        {
            // log some bad stuff here
        }

        return JObject.Parse(response.Content);
    }

【问题讨论】:

  • isBusy 字段是受保护的还是私有的?
  • 未指定,因此我认为它是内部的
  • 我认为这使它成为私有的,但我不相信这实际上是原因 - stackoverflow.com/questions/2521459/…
  • 我只是将其公开以仔细检查,是的,将 isBusy 设置为 true 后它仍然没有出现
  • @user1818298 你可以调试 if (!isAuthenticated ) 这一行,当你调用OnLogin方法时,看看它是否在IsBusy = true;之后立即进入它,如果是,尝试使用@987654330 @ 而不是 client.Execute

标签: c# xamarin.forms visual-studio-2019 activity-indicator


【解决方案1】:

通过Authenticate方法的更新代码,你可以改变

 client.Execute;

 client.ExecuteAsync

在这种情况下,您将按预期显示 ActivityIndi​​cator

【讨论】:

    【解决方案2】:

    然后确保您的视图模型实现 INotifyPropertyChanged:

        public bool IsBusy
        {
            set { isBusy = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsBusy))); }
            get { return isBusy; }
        }
    

    【讨论】:

      猜你喜欢
      • 2016-01-06
      • 1970-01-01
      • 2012-08-14
      • 1970-01-01
      • 1970-01-01
      • 2016-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多