C# Xamarin - Binding data to UICollectionViewCell using SetValueForKey
<p>I am having significant problems using Xamarin.iOS. </p>

<p>I come from a MVC5 web background and would often bind data to DOM elements (for example with JS <code>data-</code> attributes). I want to achieve a similar pattern in Xamarin.iOS.</p>

<p>From what I gather in Xamarin's documentation (which always seems to be based on obsolete versions of the framework) I need to bind data (but not display it) to a <code>UICollectionViewCell</code> using the KVC pattern. </p>

<p>Is the best method calling <code>SetValueForKey(NSObject object, NString key)</code> within my UpdateCell method (NOTE: I have changed the params to be generic): </p>

<pre><code> public class MyClassCollectionViewCell : UICollectionViewCell 
 {
     [Outlet]
     UILabel NameLabel { get; set; }

     public BaseCell (IntPtr handle) : base (handle)
     {
         this.NameLabel = new UILabel();
     }

     public virtual void UpdateCell(MyClass myClassObject)
     {
         // Display the "Name" within the UILabel outlet
         this.NameLabel.Text = myClassObject.Name;

         // This being my custom cell which inherits from UICollectionViewCell
         this.SetValueForKey(myClassObject, "BoundMyClassObject");

         // remainder omitted for brevity
     }
 }
</code></pre>

<p>And MyClass.cs (again, not it's real name but for illustration)</p>

<pre><code>public class MyClass 
{
     [JsonProperty("Id")]
     public int Id { get; set; }

     [JsonProperty("Name")]
     public string Name { get; set; }

     // more props omitted for brevity
}
</code></pre>

<p>Is the problem that the object I am trying to bind does not inherit from <code>NSObject</code> and therefore will not work with <code>SetValueForKey</code>. </p>

<p>I am hoping to bind the object to a cell, tap the cell, retrieve data bound to cell and finally make a REST call using the bound data. </p>

<p>The reason for this? Well I want the "Name" MyClass property to appear on the <code>UICollectionViewCell</code>'s label and the "Id" to be accessible for the REST call but not displayed to the user. Currently the label appears the TapGesture works but I am unable to retrieve the value for myClassObject.Id and thus cannot make a web call!</p>

<p>The <code>UITapGestureRecognizer</code> is wired up to the <code>UICollectionView</code> within  my <code>UICollectionViewController</code>- code not required for scope of question) and corrently fires an event but requires the value for key "BoundMyClassObject" or myClassObject.Id to POST as JSON...</p>

<p>Make sense?</p>

<p>Please help me out as there is very little information within Xamarin documentation and forums.</p>

<p>All the best,</p>

<p>John</p>

<p><strong><em>EDIT</em></strong></p>

<p>As <a href="https://forums.xamarin.com/discussion/5130/setvalueforkey" rel="nofollow">@AdamKemp</a> points out in the post here <code>SetValueForKey</code> is meant for <code>NSObject</code>s.</p>

<p>So I refactored the code in <code>MyClass.cs</code> as follows</p>

<p>[Register("MyClass)]
    public class My Class : NSObject
    {
        public MyClass() { }</p>

<pre><code>    public MyClass(int ID)
    {
        this.Id = ID;
    }

    private int _Id = 0;
    [Export("Id")]
    public int Id
    {
        get
        {
            return _Id;
        }
        set
        {
            WillChangeValue("Id");
            _Id = value;
            DidChangeValue("Id");
        }
    }

    // same for Name property
}
</code></pre>

<p>However when I call <code>SetValueForKey</code> within my <code>UpdateCell</code> method</p>

<pre><code> MyClass myClassObject = newMyClass(7); // int passed to constructor for illustration in my real code it's dynamic

    this.SetValueForKey(myClassObject, "MyClassObject");
</code></pre>

<p>I encounter the following error</p>

<pre><code>Foundation.MonoTouchException: Objective-C exception thrown.  Name: NSUnknownKeyException Reason: [&lt;UICollectionViewCell 0x7e433a30&gt; setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key MyClassObject.
</code></pre>