I am attempting to create a bindable RadioElement to use in a MonoTouch.Dialog implementation in MvvmCross, and following the pattern in https://github.com/MvvmCross/MvvmCross-Tutorials/tree/master/DialogExamples/DialogExamples.Touch/BindableElements (as suggested in MvvmCross Monotouch.Dialog binding data to a table), I created the following class:
public class MvxBindableRadioElement : RadioElement, IBindableElement
{
public IMvxBindingContext BindingContext { get; set; }
public MvxBindableRadioElement ()
{
this.CreateBindingContext();
this.DelayBind(() => {
var set = this.CreateBindingSet<MvxBindableRadioElement, PropertyCategory>();
set.Bind().For(me => me.Caption).To(p => p.Id);
set.Bind().For(me => me.Value).To(p => p.Value);
set.Apply();
});
}
protected override void Dispose(bool disposing)
{
if (disposing) {
BindingContext.ClearAllBindings();
}
base.Dispose(disposing);
}
public virtual object DataContext
{
get { return BindingContext.DataContext; }
set { BindingContext.DataContext = value; }
}
}
PropertyCategory
is a basic Model:
public class PropertyCategory
{
public int Id { get; set; }
public string Value { get; set; }
}
This is used as follows:
new Section {
new RootElement ("Category", new RadioGroup ()) {
new BindableSection<MvxBindableRadioElement> ().Bind(bindings, e => e.ItemsSource, vm => vm.PropertyCategories)
}.Bind (bindings, e => e.RadioSelected, vm => vm.PropertyCategory) as Element
}
where BindableSection
is taken from the MvvmCross repo mentioned above.
Debugging I am able to verify that the newElements
variable of MvxBindableSection
is correctly populated with MvxBindableRadioElement
s, but the following error occurs when the TableView.ReloadData()
line is executed:
MvxBind:Error: 12.12 Problem seen during binding execution for binding ItemsSource for PropertyCategories - problem TargetInvocationException: Exception has been thrown by the target of an invocation.
at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0005c] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:238
at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Reflection/MethodBase.cs:114
at Cirrious.MvvmCross.Binding.Bindings.Target.MvxPropertyInfoTargetBinding.SetValueImpl (System.Object target, System.Object value) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Binding.Bindings.Target.MvxConvertingTargetBinding.SetValue (System.Object value) [0x00000] in <filename unknown>:0
at Cirrious.MvvmCross.Binding.Bindings.MvxFullBinding.UpdateTargetFromSource (System.Object value) [0x00000] in <filename unknown>:0
InnerException was NullReferenceException: Object reference not set to an instance of an object
at <redacted>.iOS.Views.MvxBindableSection`1[<redacted>.Views.MvxBindableRadioElement].NotifyDataSetChanged () [0x000b9] in <redacted>/MonoTouch.Dialog/MvxBindableSection.cs:87
at <redacted>.iOS.Views.MvxBindableSection`1[<redacted>.Views.MvxBindableRadioElement].SetItemsSource (IEnumerable value) [0x00094] in <redacted>/MonoTouch.Dialog/MvxBindableSection.cs:56
at <redacted>.iOS.Views.MvxBindableSection`1[<redacted>.Views.MvxBindableRadioElement].set_ItemsSource (IEnumerable value) [0x00003] in <redacted>/MonoTouch.Dialog/MvxBindableSection.cs:30
at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00044] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:230
Troubleshooting this, I replaced the MvxBindableRadioElement
with CustomStringElement
from the MvvmCross repo mentioned above:
new MvxBindableSection<CustomStringElement>().Bind(bindings, element => element.ItemsSource, vm => vm.PropertyCategories)
This works like a charm. Why does the CustomStringElement
work, but not theMvxBindableRadioElement
? Do I have to create a bindable RadioGroup
that wraps the MvxBindableRadioElement
s?
EDIT:
Here is the Inner Exception (NullReferenceException):
at CrossUI.Touch.Dialog.Elements.RadioElement.SubscribeToRoot () [0x00000] in <filename unknown>:0
at CrossUI.Touch.Dialog.Elements.RadioElement.GetCellImpl (MonoTouch.UIKit.UITableView tv) [0x00000] in <filename unknown>:0
at CrossUI.Touch.Dialog.Elements.Element.GetCell (MonoTouch.UIKit.UITableView tv) [0x00000] in <filename unknown>:0
at CrossUI.Touch.Dialog.DialogViewController+Source.GetCell (MonoTouch.UIKit.UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath) [0x00000] in <filename unknown>:0
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 PGPCapture.iOS.Application.Main (System.String[] args) [0x00008] in <redacted>/Main.cs:21