0

我正在尝试在我的视图中使用 prismMvvm:ViewModelLocator.AutoWireViewModel="True" 自动连接 ViewModel。对于 UWp,它工作得很好。但是在 Android 和 WASM 中,View 无法使用 Prism 在我的 Uno 平台应用程序中连接 ViewModel。


<UserControl
    x:Class="RepayablClient.Shared.Views.Login"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:prismMvvm="using:Prism.Mvvm"
    HorizontalAlignment="Stretch"
    VerticalAlignment="Stretch"
    prismMvvm:ViewModelLocator.AutoWireViewModel="True"
    mc:Ignorable="d">
    <Grid Background="#881798">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Grid
            Width="250"
            Height="300"
            HorizontalAlignment="Center"
            VerticalAlignment="Center">
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="25" />
                <RowDefinition Height="25" />
            </Grid.RowDefinitions>
            <Image
                Grid.Row="0"
                Source="/Assets/Icon.png"
                Stretch="Fill" />
            <TextBlock Grid.Row="1" Text="{Binding LoginUser}" />
            <ProgressBar
                Grid.Row="2"
                Width="250"
                Margin="0,20,0,0"
                Foreground="White"
                IsIndeterminate="True"
                ShowError="False"
                ShowPaused="False" />
        </Grid>
    </Grid>
</UserControl>

using Microsoft.Identity.Client;
using RepayablClient.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace RepayablClient.Shared.ViewModels
{
    public class LoginViewModel : ViewModelBase
    {
        //public ICommand LoginCommand { get; set; }
        string graphAPIEndpoint = "https://graph.microsoft.com/v1.0/me";
        private string _loginUser;

        public string LoginUser
        {
            get { return _loginUser; }
            set
            {
                _loginUser = value;
                RaisePropertyChanged();
            }
        }
        public LoginViewModel()
        {
            Title = "Login Page";
            LoginUser = "Attempt to Login";
            _ = LoginCommandExecutedAsync();
            //LoginCommand = new AsyncCommand(LoginCommandExecutedAsync);
        }

        private async Task LoginCommandExecutedAsync()
        {

            AuthenticationResult authResult = null;
            IEnumerable<IAccount> accounts = await App.publicClientApplication.GetAccountsAsync().ConfigureAwait(false);
            IAccount firstAccount = accounts.FirstOrDefault();
            try
            {
                authResult = await App.publicClientApplication.AcquireTokenSilent(Consts.Scopes, firstAccount)
                                                        .ExecuteAsync();
            }
            catch (MsalUiRequiredException ex)
            {
                System.Diagnostics.Debug.WriteLine($"MsalUiRequiredException: {ex.Message}");
                try
                {
                    authResult = await App.publicClientApplication.AcquireTokenInteractive(Consts.Scopes)
                       .ExecuteAsync();
                }
                catch (MsalException msalex)
                {
                    // await DisplayMessageAsync($"Error Acquiring Token:{System.Environment.NewLine}{msalex}");
                }
            }
            catch
            {
                //  await DisplayMessageAsync($"Error Acquiring Token Silently:{System.Environment.NewLine}{ex}");
                return;
            }
            if (authResult != null)
            {
                var content = await GetHttpContentWithTokenAsync(graphAPIEndpoint,
                                                            authResult.AccessToken).ConfigureAwait(false);

                LoginUser = content;

            }
        }
        public async Task<string> GetHttpContentWithTokenAsync(string url, string token)
        {
            var httpClient = new System.Net.Http.HttpClient();
            System.Net.Http.HttpResponseMessage response;
            try
            {
                var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, url);
                // Add the token in Authorization header
                request.Headers.Authorization =
                  new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
                response = await httpClient.SendAsync(request);
                var content = await response.Content.ReadAsStringAsync();
                return content;
            }
            catch (Exception ex)
            {
                return ex.ToString();
            }
        }
    }
}

更多详情请访问我的仓库:https ://github.com/avikeid2007/Repayabl

4

1 回答 1

1

您面临的问题仍然存在于 Uno,很快就会调整。基本上,如果您使用 a UserControl,则在创建控件时可能不会考虑其中定义的某些属性。

您可以通过以下两种方式之一解决此问题:

  • 将 更改UserControlContentControl
  • 在您的 csproj 中添加以下属性:
<UnoSkipUserControlsInVisualTree>false</UnoSkipUserControlsInVisualTree>

这个问题是 Android 有一个非常短的 UI 线程堆栈空间的遗留问题,并且可视化树中的每一层都很重要。它不再那么重要了。

于 2020-05-04T15:12:40.187 回答