1

MvvmCross を使用した MonoTouch プロジェクトがあります。コア プロジェクト コードをコンパイルできるところまで来ました (かなりの労力を要します)。現在、iOS 用のビューを作成しています。Xamarin ツールの最新の安定版リリースと MvvmCross を実行します。また、XCode 5 がインストールされた iOS7 SDK に対して実行しています。

まず、メイン ビュー モデルにテキスト フィールドをバインドする非常に基本的なビューを作成しました。ビュー内の関連コードは次のとおりです。

[Register("MainView")]
public partial class MainView : MvxViewController
{
    public override void ViewDidLoad()
    {
        View = new UIView { BackgroundColor = UIColor.White };

        base.ViewDidLoad();

        var uiTextField = new UITextField(new RectangleF(0, 100, 320, 100));
        Add(uiTextField);

        this.CreateBinding(uiTextField).To<MainViewModel>(vm => vm.IsDebug).Apply();

    }
}

ただし、バインディングは、次のスタック トレースで NullReference 例外をスローします。

1[MonoTouch.UIKit.UITextField].SourcePropertyPath[MainViewModel] (System.Linq.Expressions.ExpressionSystem.NullReferenceException: オブジェクト参照が Cirrious.MvvmCross.Binding.BindingContext.MvxBaseFluentBindingDescription 1 sourceProperty) [0x00000] in :0 at Cirrious.MvvmCross.Binding.BindingContext.MvxFluentBindingDescriptionのオブジェクトのインスタンスに設定されていません1[MonoTouch.UIKit.UITextField].To[MainViewModel] (System.Linq.Expressions.Expression1 sourceProperty) [0x00000] in :0 at ProjectX.Views.MainView.ViewDidLoad () [0x000a4] in /Users/jerriepelser/Development/1degree Software/ProjectX/Source/ProjectX.MonoTouch/Views/MainView.cs:26 at at (wrapper managed-to-native) MonoTouch.ObjCRuntime.Messaging:void_objc_msgSend (intptr,intptr) at MonoTouch.UIKit.UIWindow.MakeKeyAndVisible () [0x00010] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIWindow.g .cs:129 at ProjectX.AppDelegate.FinishedLaunching (MonoTouch.UIKit.UIApplication アプリ、MonoTouch.Foundation.NSDictionary オプション) [0x0003c] /Users/jerriepelser/Development/1degree Software/ProjectX/Source/ProjectX.MonoTouch/AppDelegate.cs :27 at at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr) at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38 at ProjectX.Application.Main (System.String[] args) [0x00008] in /Users /jerriepelser/Development/1degree Software/ProjectX/Source/ProjectX.MonoTouch/Main.cs:16

バインディングの前にブレークポイントを設定すると、ViewModel がベース MvxViewController クラスで正しく設定されていることが確認できるので、ViewModel が設定されていなくても問題ありません。

また、データバインディングを行う次の方法も試しました。

var set = this.CreateBindingSet<MainView, MainViewModel> ();
set.Bind (uiTextField).To (vm => vm.IsDebug);
set.Apply ();

それでも NullReference 例外が発生しますが、次のスタック トレースがあります。

1[MonoTouch.UIKit.UITextField].SourcePropertyPath[MainViewModel] (System.Linq.Expressions.ExpressionSystem.NullReferenceException: オブジェクト参照が Cirrious.MvvmCross.Binding.BindingContext.MvxBaseFluentBindingDescription 1 sourceProperty) [0x00000] in :0 at Cirrious.MvvmCross.Binding.BindingContext.MvxFluentBindingDescriptionのオブジェクトのインスタンスに設定されていません2[MonoTouch.UIKit.UITextField,OneLove.Core.ViewModels.MainViewModel].To (System.Linq.Expressions.Expression1 sourceProperty) [0x00000] in :0 at OneLove.Views.MainView.ViewDidLoad () [0x000a6] in /Users/jerriepelser/Development/1degree Software/OneLove/Source/OneLove.MonoTouch/Views/MainView.cs:29 at at at (wrapper managed-to-native) MonoTouch.ObjCRuntime.Messaging:void_objc_msgSend (intptr,intptr) at MonoTouch.UIKit.UIWindow.MakeKeyAndVisible () [0x00010] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIWindow.g .cs:129 at OneLove.AppDelegate.FinishedLaunching (MonoTouch.UIKit.UIApplication アプリ、MonoTouch.Foundation.NSDictionary オプション) [0x0003c] /Users/jerriepelser/Development/1degree Software/OneLove/Source/OneLove.MonoTouch/AppDelegate.cs :27 at at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr) at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38 at OneLove.Application.Main ( System.String[] args) [0x00008] in /Users/jerriepelser/Development/1degree Software/OneLove/Source/OneLove.MonoTouch/Main.cs:16

MvvmCross のデバッグ出力を見ても、何が問題なのかわかりません。何か案は?

4

3 に答える 3

0

これはより良い答えになるはずです:

  • ステップ 1: 混乱しています: 独自のビューを作成する場合は、ViewDidLoad の代わりに LoadView をオーバーライドします。関連する Xib がないことを確認します。
  • ステップ 2: MvvmCross の欠点のため、loadview で ViewDidLoad を呼び出します (ViewDidLoad の後に ViewModel をバインドしますが、ViewDidLoad は Xib の後にのみ呼び出されます)。

MvvmCross は、ViewDidLoad で定義した (後で作成された) ビューではなく、元のビューへの参照を保持していると思います。

Xib なしで MvvmCross を使用すると問題なく動作し (Xib を作成することはもうありません)、XibFree を強くお勧めします (フォークを使用して機能を拡張します)。

于 2013-09-23T14:22:14.747 に答える
0

コードから生成されたビューを使用して同じ問題に遭遇しました。

Viewmodel は設定されていますが、bindingcontext は完全には設定されていません。これは、発生する他の問題に対処するための私のプロジェクトのコード例です。

public abstract class IndexBaseFragment<T> : MvxFragment where T : class, IMvxViewModel {
        public static int WRAP = ViewGroup.LayoutParams.WrapContent;
        public static int FILL = ViewGroup.LayoutParams.FillParent;

        public LinearLayout NewVerticalLinearLayout(Orientation orientation, Boolean fillparent) {
            var ll = new LinearLayout (Activity) { Orientation = orientation };
            ll.LayoutParameters = new ViewGroup.LayoutParams (FILL, fillparent ? FILL : WRAP);
            return ll;
        }

        public new T ViewModel { get { return base.ViewModel as T; } set { base.ViewModel = value; } } 

        // These are the available controls
        protected ListView list {get; set;}
        protected MvxListView ListAsMvxListView {get { return (MvxListView) list; }}
        protected TextView emptytext { get; set; }
        protected TextView title { get; set; }
        protected Button twobuttonklein { get; set; }
        protected Button twobuttongroot { get; set; }
        protected EditText zoekvak {get; set;}



        public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            base.OnCreateView (inflater, container, savedInstanceState);

            var layout = NewVerticalLinearLayout (Orientation.Vertical, true);


            if (ViewModel == null)
                ViewModel = Mvx.IocConstruct<T> ();
            BindingContext = new MvxAndroidBindingContext (Activity, new MvxSimpleLayoutInflater(inflater), ViewModel);
            using (new MvxBindingContextStackRegistration<IMvxAndroidBindingContext>(((IMvxAndroidBindingContext) this.BindingContext)))
            {
                //var layout = NewVerticalLinearLayout (Orientation.Vertical, true);
                layout.SetBackgroundColor (Color.ParseColor("#FFFFFF"));
                var titlelayer = NewVerticalLinearLayout (Orientation.Horizontal, false);
                titlelayer.LayoutParameters.Height = 40;
                title = new TextView (Activity) { LayoutParameters = new ViewGroup.LayoutParams (FILL, FILL) };
                title.SetTextColor (Color.ParseColor ("#212121"));
                title.SetPadding(0, 10, 0, 0);
                title.TextSize = 18;
                var titlebutton = new Button (Activity) { LayoutParameters = new ViewGroup.LayoutParams (WRAP, FILL) };
                titlelayer.AddView (title);
                titlelayer.AddView (titlebutton);
                layout.AddView (titlelayer);

                var twobuttonlayer = NewVerticalLinearLayout (Orientation.Horizontal, false);
                twobuttonlayer.LayoutParameters.Height = 40;
                twobuttonklein = new Button (Activity) { LayoutParameters = new ViewGroup.LayoutParams (FILL, WRAP) };
                twobuttonklein.Text = "Klein";
                twobuttonklein.SetBackgroundResource (Resource.Drawable.kleingrootbutton);
                twobuttongroot = new Button(Activity){ LayoutParameters = new ViewGroup.LayoutParams (FILL, WRAP) };
                twobuttongroot.Text = "Middel/groot";
                twobuttongroot.SetBackgroundResource (Resource.Drawable.kleingrootbutton);
                twobuttonlayer.AddView (twobuttonklein);
                twobuttonlayer.AddView (twobuttongroot);
                layout.AddView (twobuttonlayer);

                zoekvak = new EditText (Activity) { LayoutParameters = new ViewGroup.LayoutParams (FILL, WRAP) };
                zoekvak.Hint = "Zoek in inhoudsopgave";
                layout.AddView (zoekvak);

                emptytext = new TextView (Activity) { LayoutParameters = new ViewGroup.LayoutParams (FILL, FILL),
                    Text = "Er zijn geen resultaten." };
                layout.AddView (emptytext);

                CreateList();

                layout.AddView (list);


            }




            //var view = this.BindingInflate(Resource.Layout.IndexTocView, null);
            Console.WriteLine ("LAYOUT RETURNED");

            return layout;
        }

        protected abstract void BindView();

        protected MvxAdapter listadapter { get; set; }


        protected virtual void CreateList () {
            // let op, deze code is nog voor de speciale situatie, en dat moet juist andersom.
            listadapter = new MvxAdapter(this.Activity, (IMvxAndroidBindingContext)BindingContext);

            list = new MvxListView(Activity, null, listadapter) { LayoutParameters = new ViewGroup.LayoutParams(FILL, FILL) };
            list.SetMinimumHeight(50);

        }

        public override void OnResume ()
        {
            base.OnResume ();
            BindView ();
        }




    }
于 2013-09-23T14:14:15.557 に答える