2

これは、プログラムによるMvvmCross AndroidDialogBingに関する投稿のフォローアップです。

DroidプロジェクトにDialogのバインディングを実装しました。

    this.Root = new RootElement("Customer Info")
    {
        new Section("Private Configuration")
        {
            new EntryElement("Pin:").Bind(this, "{'Value':{'Path':'Configuration.Pin'}}"),
            new EntryElement("Name:").Bind(this, "{'Value':{'Path':'Configuration.Name', 'Mode':'TwoWay'}}"),
        };
    };

テスト目的で、バインドにTwoWayを追加しました。Configuration.Name

現在の問題は、バインドがOneWayでのみ機能していることです。ビューで何かを変更してもオブジェクトは更新されませんが、オブジェクトが変更されるとビューに通知されます。これは、上記の両方のバインドで発生します(バインドモードでのTwoWayの有無にかかわらず)。

これは、MvvmCrossフレームワークを使用して、viewModelsによって制御される、バインドおよび複数のビューで動作する完全なDroid.Dialogプロジェクトを持つために残された唯一のものです。

デバッグできたもの(VS2010ではDroidコードのみ、PCLなし)から、のテキストを変更するたびにEntryElementOnTextChangedメソッドが呼び出され、プロパティValueが更新されます。

EntryElement.cs

    public virtual void OnTextChanged(string newText)
    {
        //Log.Info("Just playing","New text:" + newText);
        OnUserValueChanged(newText);
    }

ValueElement.cs

    protected void OnUserValueChanged(TValueType newValue)
    {
        Value = newValue;
        FireValueChanged();
    }

    protected virtual void FireValueChanged()
    {
        var handler = ValueChanged;
        if (handler != null)
            handler(this, EventArgs.Empty);
    }

これが私がコアプロジェクトとドロイドプロジェクトに持っているコードです

BaseViewModel.cs

    public class BaseViewModel : MvxViewModel, IMvxServiceConsumer
    {
        protected IConfigurationDataStore ConfigDataStore
        {
            get
            {
                if (_configDataStore == null)
                    _configDataStore = this.GetService<IConfigurationDataStore>();

                return _configDataStore;
            }
        }
        private IConfigurationDataStore _configDataStore;
    }

EditConfigurationViewModel.cs

    public class EditConfigurationViewModel : BaseViewModel, IEditConfigurationViewModel
    {
        public ConfigurationSet Configuration
        {
            get { return _configuration; }
            set
            {
                if (_configuration != value)
                {
                    _configuration = value;
                    RaisePropertyChanged(() => Configuration);
                }
            }
        }
        private ConfigurationSet _configuration;

        public EditConfigurationViewModel(string id)
        {
            Guid value;
            if (string.IsNullOrEmpty(id) || !Guid.TryParse(id, out value))
            {
                Configuration = new ConfigurationSet();
            }
            else
            {
                Configuration = ConfigDataStore.GetConfiguration(value);
            }
        }

        public void SaveConfiguration()
        {
            ConfigDataStore.UpdateConfiguration(Configuration);
        }
    }

ConfigurationSet.cs

    public class ConfigurationSet : MvxNotifyPropertyChanged
    {
        public string Pin
        {
            get { return _pin; }
            set
            {
                if (_pin != value)
                {
                    _pin = value;
                    RaisePropertyChanged(() => Pin);
                }
            }
        }
        private string _pin;

        public string Name
        {
            get { return _name; }
            set
            {
                //if (_name != value)
                //{
                    _name = value;
                    RaisePropertyChanged(()=> Name);
                //}
            }
        }
        private string _name;

        public string PrivateDescription
        {
            get { return _privateDescription; }
            set
            {
                if (_privateDescription != value)
                {
                    _privateDescription = value;
                    RaisePropertyChanged(() => PrivateDescription);
                }
            }
        }
        private string _privateDescription;
    }

ドロイド

EditConfigurationView

    public class EditConfigurationView : MvxBindingDialogActivityView<EditConfigurationViewModel>, IMvxServiceConsumer
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            DroidResources.Initialise(typeof(Resource.Layout));

            Root = new RootElement()
                {
                    new Section("Private Configuration")
                    {
                        new EntryElement("Pin:").Bind(this, "{'Value':{'Path':'Configuration.Pin'}}"),
                        new EntryElement("Name:").Bind(this, "{'Value':{'Path':'Configuration.Name'}}"),
                        new EntryElement("Description:").Bind(this, "{'Value':{'Path':'Configuration.PrivateDescription'}}")
                    }
                };
        }

        public override void OnBackPressed()
        {
            ViewModel.SaveConfiguration();

            base.OnBackPressed();
        }

        protected override void OnViewModelSet()
        {

        }
    }
4

3 に答える 3

2

https://github.com/zleao/MvvmCross.Dialogでリポジトリを見た後の2番目の回答


追加情報をありがとう。

サンプルはまだ実行していませんが、問題を再現するための簡単なコードを確認すると非常に役立ちます。

問題はおそらくセットアップファイルにあると思います-https://github.com/zleao/MvvmCross.Dialog/blob/master/MvvmCross.Dialog.UI.Droid/Setup.cs

そこに継承されるMvxBaseAndroidBindingSetupセットアップは、すべての基本セットアップクラスでCirrious.MvvmCross.Binding.Droidあり、それ自体はMvxBaseAndroidSetupから継承します。Cirrious.MvvmCross.Droid

「バインドのみ」に加えてダイアログコードを使用しているため、セットアップをさらに進める必要があります。から追加する必要がありMvxBaseAndroidDialogBindingSetupますCirrious.MvvmCross.Dialog.DroidValueこのクラスは、すべてのValueElementインスタンスでの双方向バインディングの登録を含む、いくつかの重要なステップを追加します。以下を参照してください。

    protected override void FillTargetFactories(
        Cirrious.MvvmCross.Binding.Interfaces.Bindings.Target.Construction.IMvxTargetBindingFactoryRegistry registry)
    {
        registry.RegisterFactory(new MvxPropertyInfoTargetBindingFactory(typeof (ValueElement), "Value",
                                                                         (element, propertyInfo) =>
                                                                         new MvxElementValueTargetBinding(element,
                                                                                                          propertyInfo)));
        base.FillTargetFactories(registry);
    }

https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.Dialog.Droid/MvxBaseAndroidDialogBindingSetup.cs _


したがって、問題を修正するには、からセットアップを継承してみてください MvxBaseAndroidDialogBindingSetup


MvvmCrossのレイヤーの詳細については、http: //slodge.blogspot.co.uk/2012/12/a-short-guide-to-layers-of-mvvmcross.htmlを参照してください。


これが問題の解決に役立つことを願っています。

提供された優れたレベルの詳細に感謝します。

ただし、Droid.Dialogコードは、タッチダイアログコードに比べてまだかなり若いため、途中で本物のバグや問題が発生する可能性があることに注意してください。それらにぶつかったら、ここで質問するか、バグである場合は、https://github.com/slodge/MvvmCross/issues?state=openのIssuesにログに記録してください。

スチュアート

于 2013-01-26T10:48:56.400 に答える
1

変更したCustomerManagementサンプルアプリでこれをテストしました。このバインディングは双方向で正常に機能しています。

私のコード:

        Root = new RootElement()
            {
                new Section("Customer Info")
                    {
                        new EntryElement("Name").Bind(this, "{'Value':{'Path':'Customer.Name'}}"),
                        new EntryElement("Website").Bind(this, "{'Value':{'Path':'Customer.Website'}}"),
                        new EntryElement("Phone").Bind(this, "{'Value':{'Path':'Customer.PrimaryPhone'}}"),
                    }
            };

私のViewModelとCustomerオブジェクトは次のとおりです。

public abstract class BaseEditCustomerViewModel
    : BaseViewModel
{
    private Customer _customer;
    public Customer Customer
    {
        get { return _customer; }
        private set { _customer = value; RaisePropertyChanged("Customer"); }
    }

    // ...
}

public class Customer : MvxNotifyPropertyChanged
{
    public Customer()
    {
    }

    private string _name;
    public string Name
    {
        get { return _name; }
        set { _name = value; RaisePropertyChanged("Name"); }
    }

    private string _website;
    public string Website
    {
        get { return _website; }
        set { _website = value; RaisePropertyChanged("Website"); }
    }

    private string _primaryPhone;
    public string PrimaryPhone
    {
        get { return _primaryPhone; }
        set { _primaryPhone = value; RaisePropertyChanged("PrimaryPhone"); }
    }

    // ...
}

あなたの説明から、明らかなエラーを見つけることができませんでした-明らかにすべての詳細を見ることができませんが-たとえば、ViewModel側のConfigurationオブジェクトは何ですか?


これがバグである可能性があると思われる場合は、https://github.com/slodge/MvvmCross/issues/newにログを記録するのがおそらく最も簡単です。

バグに含めることができる詳細が多ければ多いほど、バグはより早く調べられます。たとえば、問題を再現するサンプルのgithubリポジトリを含めることができれば、開発者はすばやく簡単にテストできます。代わりに、指示を提供するだけの場合、開発者がテストするのに1時間以上かかる可能性があります。そのため、開発者が「暇な時間」になるのを待つ必要があります。


「デバッグ...VS2010ではDroidコードのみでPCLは使用しない」に関する苦情については、Xamarinでこれを提起したことを確認してください。これらの問題を修正する唯一の方法は、有料の顧客から問題について報告された場合です。

于 2013-01-22T18:02:44.073 に答える
0

これはiOSでも必要です。

public class Setup : MvxIosDialogSetup//MvxIosSetup
于 2016-12-11T15:42:53.187 に答える