This is a follow up of the post about MvvmCross Android Dialog Bing Programmatically
I’ve implemented the bindings of a Dialog in a Droid project:
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'}}"),
};
};
I’ve added the TwoWay in the Configuration.Name bind just for test purposes.
The problem now is that the bind is working only in OneWay. The object is not updated if I change something in the view, but the view is notified if the object is changed. This happens in both binds described above (with or without TwoWay in bind Mode).
This is the only thing left to have a full Droid.Dialog project, working with bind and multiple views, controlled by viewModels, using MvvmCross framework.
From what I’ve been able to debug (only Droid code and no PCL, in VS2010), every time I change the text in the EntryElement, the OnTextChanged method is called and the property Value is beeing updated.
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);
}
Here’s the code I have in core and droid projects
CORE
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;
}
DROID
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()
{
}
}
Second answer after seeing your repo on https://github.com/zleao/MvvmCross.Dialog
Thanks for the additional information.
I’ve not run your sample yet, but seeing the simple code to reproduce the problem helps a lot.
I think the problem is probably in your Setup file – https://github.com/zleao/MvvmCross.Dialog/blob/master/MvvmCross.Dialog.UI.Droid/Setup.cs
The Setup there inherits from
MvxBaseAndroidBindingSetupwhich is the base setup class for everything inCirrious.MvvmCross.Binding.Droidand which itself inherits fromMvxBaseAndroidSetupfromCirrious.MvvmCross.DroidSince you are using the Dialog code in addition to “just Binding” then you need to take your setup further – you need to add
MvxBaseAndroidDialogBindingSetupfromCirrious.MvvmCross.Dialog.Droid. This class adds a number of important steps including registering a two-way binding forValueon allValueElementinstances – see:in https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.Dialog.Droid/MvxBaseAndroidDialogBindingSetup.cs
So – to try to fix the problem, try inheriting Setup from
MvxBaseAndroidDialogBindingSetupFor more info about the layers of MvvmCross, please see http://slodge.blogspot.co.uk/2012/12/a-short-guide-to-layers-of-mvvmcross.html
I hope this helps and solves the problem.
Thanks for the excellent level of detail supplied.
Please do note, though, that the Droid.Dialog code is still quite young compared to the Touch Dialog code – so you may hit genuine bugs and problems along the way. When you hit them, please do ask question here, or if they are bugs, then please do log them on Issues on https://github.com/slodge/MvvmCross/issues?state=open
Stuart