Android / WASM: prismMvvm: ViewModelLocator.AutoWireViewModel = "True" не является подключением ViewModel для Android и Wasm - PullRequest
0 голосов
/ 03 мая 2020

Я пытаюсь автоматически подключить ViewModel, используя prismMvvm: ViewModelLocator.AutoWireViewModel = "True" в моем представлении. Для UWp это работает отлично. Но с Android и WASM View не может подключить ViewModel в моем приложении на платформе Uno с помощью Prism.


<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

1 Ответ

1 голос
/ 04 мая 2020

Вы столкнулись с проблемой, которая все еще стоит в Uno, которая будет вскоре исправлена. В основном, если вы используете UserControl, некоторые из определенных там свойств могут не учитываться при создании элемента управления.

Это можно исправить одним из двух способов:

  • Измените UserControl на ContentControl
  • Добавьте следующее свойство в свой csproj:
<UnoSkipUserControlsInVisualTree>false</UnoSkipUserControlsInVisualTree>

Эта проблема является пережитком времени, когда Android имел очень короткое пространство стека пользовательского интерфейса, и каждый слой в визуальном дереве учитывался. Это уже не так критично.

...