【解決方法】Mvvmcross navigate コマンドで system.nullreferenceexception が発生する

プログラミングQA


ボタン バインディングを持つ MvvmCross ナビゲーション コマンドでのナビゲーションに問題があります。 現在、Android でコードをテストしています。 ボタンのクリックでナビゲートしたいのですが、 IMvxNavigationServiceNavigate コマンドを設定してバインディングを作成した次のViewModelに

それは私に Exception: Default [Error] MvxAsyncCommand : exception executing taskSystem.NullReferenceException: Object reference not set to an instance of an object.

それはそのように見えます IMvxNavigationService Navigate それ自体が NullReferenceException を与えており、コマンドを設定した方法に問題はありません。

Android ログ:

pixel_2_q_10_0_-_api_29	Error	32148	Default	[Error] MvxAsyncCommand : exception executing taskSystem.NullReferenceException: Object reference not set to an instance of an object.
  at MvxFuelPriceCalculator.Core.ViewModels.FuelPriceCalcViewModel.<get_NavigateCommand>b__56_0 () [0x00000] in C:\Users\Work & Education\Documents\Programming\MvxFuelPriceCalculator\src\MvxFuelPriceCalculator.Core\ViewModels\FuelPriceCalcViewModel.cs:216 
  at MvvmCross.Commands.MvxAsyncCommandBase.ExecuteConcurrentAsync (System.Object parameter, System.Boolean hideCanceledException06-22 13:23:16.852 E/Default (32148):   at MvvmCross.Commands.MvxAsyncCommand+<>c__DisplayClass2_0.<.ctor>b__0 (System.Threading.CancellationToken _) [0x00000] in /_/MvvmCross/Commands/MvxAsyncCommand.cs:190 
  at MvvmCross.Commands.MvxAsyncCommand.ExecuteAsyncImpl (System.Object parameter) [0x00000] in /_/MvvmCross/Commands/MvxAsyncCommand.cs:208
  at MvvmCross.Commands.MvxAsyncCommandBase.ExecuteAsync (System.Object parameter, System.Boolean hideCanceledException) [0x00040] in /_/MvvmCross/Commands/MvxAsyncCommand.cs:88
  at MvvmCross.Commands.MvxAsyncCommandBase.Execute (System.Object parameter) [0x00030] in /_/MvvmCross/Commands/MvxAsyncCommand.cs:70

FirstViewModel.cs

C#
using System.Threading.Tasks;
using System.Windows.Input;
using MvvmCross.Commands;
using MvvmCross.ViewModels;
using MvxFuelPriceCalculator.Core.Services;
using MvvmCross.Navigation;

namespace MvxApplication.Core.ViewModels
{
    public class FirstViewModel : MvxViewModel
    {
        public override async Task Initialize()
        {
            await base.Initialize();
        }

        private readonly IMvxNavigationService _navigationService;

        public FirstViewModel(IMvxNavigationService navigationService)
        {
            _navigationService = navigationService;
        }

        private IMvxAsyncCommand _navigateCommand;
        public IMvxAsyncCommand NavigateCommand
        {
            get
            {   // Breakes here 
                _navigateCommand = _navigateCommand ??
                new MvxAsyncCommand(() => 
                _navigationService.Navigate<SecondViewModel>());
                return _navigateCommand;
            }
        }
    }
}

SecondViewModel.cs

C#
using MvvmCross.ViewModels;

namespace MvxApplication.Core.ViewModels
{
    public class SecondViewModel : MvxViewModel
    {

    }
}

FirstView.cs

C#
using Android.Text;
using Android.Util;
using Android.Views;
using Android.Widget;
using MvvmCross.Platforms.Android.Views;
using MvxApplication.Core.ViewModels;

namespace MvxApplication.Droid.Views
{
    [Activity(Label = "", MainLauncher = false)]
    public class FirstView : MvxActivity<FirstViewModel>
    {

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView(Resource.Layout.first_layout);

            RelativeLayout relativeLayout = FindViewById<RelativeLayout> 
            (Resource.Id.relativeLayout);
        }
    }
}

first_layout.axml

axml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:id="@+id/relativeLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/design_dark_default_color_background" >

    <Button android:id="@+id/top_bar_btn"
        android:layout_width="180dp"
        android:layout_height="40dp"
        android:layout_marginTop="50dp"
        android:layout_centerHorizontal="true"
        android:clickable="true"
        local:MvxBind="Click NavigateCommand"/>
</RelativeLayout>

SecondView.cs

C#
using Android.App;
using Android.OS;
using MvvmCross.Platforms.Android.Views;
using MvxApplication.Core.ViewModels;

namespace MvxApplication.Droid.Views
{
    [Activity(Label = "Second View", MainLauncher = false)]
    public class SecondView : MvxActivity<SecondViewModel>
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView(Resource.Layout.second_layout);
        }
    }
}

second_layout.axml

axml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:id="@+id/relativeLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/design_dark_default_color_background" >

    <ImageView 
        android:layout_width="match_parent"
        android:layout_height="110dp" 
        android:src="@drawable/rectangle_light"/>
</RelativeLayout>

私が試したこと:

私はドキュメンテーションに従っています ナビゲーションおまけ – ナビゲーション. そして、あまり役に立たなかったいくつかの以前の投稿を見てきました。

バインディングを確認し、プログラムでバインドしようとしました。

私もこれをやってみました この郵便受け

C#
public class SecondViewModel : MvxViewModel<FirstViewModel>

このエラーが発生するだけです

Error	CS0534	'SecondViewModel' does not implement inherited abstract member 'MvxViewModel<FirstViewModel>

私が得ることができる助けをありがとう

解決策 1

質問に書き込むための詳細情報を探したところ、IMvxNavigationService 関数が実行されていないことに気付きました。このコード:

C#
private readonly IMvxNavigationService _navigationService;

public FirstViewModel(IMvxNavigationService navigationService)
{
    _navigationService = navigationService;
}

私の問題はそれを一番上に移動することで解決しました。アプリケーションが以前にコードに到達しなかったため、これはうまくいったと思いました。 しかし、@RichardDeeming が書いたように、あまり変わらないはずです。 したがって、これは誰にとってもうまくいくとは限りません

しかし、そこに私の解決策があります

今後の編集: まず第一に、私はまだ非常に初心者です。
十分なコードが含まれていませんでした。 ICalculationService もありました。 そして、私は初期化子を持っていました。 2 つのサービスを 1 つのメンバー/関数にマージするだけです。

C#
private readonly IMvxNavigationService _navigationService;
private readonly ICalculationService _calculationService;

public FirstViewModel(IMvxNavigationService navigationService, ICalculationService calculationService)
{
     _navigationService = navigationService;
     _calculationService = calculationService;
}

コメント

タイトルとURLをコピーしました