0

View で、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 にまだ残っている問題に直面しています。これはすぐに調整されます。基本的に、 を使用するUserControlと、そこで定義されたプロパティの一部が、コントロールの作成時に考慮されない場合があります。

これは、次の 2 つの方法のいずれかで修正できます。

  • UserControlを に変更ContentControl
  • csproj に次のプロパティを追加します。
<UnoSkipUserControlsInVisualTree>false</UnoSkipUserControlsInVisualTree>

この問題は、Android の UI スレッド スタック スペースが非常に短く、ビジュアル ツリーのすべてのレイヤーがカウントされていた時代の名残です。それはもはやそれほど重要ではありません。

于 2020-05-04T15:12:40.187 に答える