2016-05-18 1 views
1

У меня возникают значительные проблемы с использованием Xamarin.iOS.C# Xamarin - привязка данных к UICollectionViewCell с использованием SetValueForKey

Я пришел из веб-фона MVC5 и часто привязывал данные к элементам DOM (например, с атрибутами JS data-). Я хочу добиться аналогичной картины в Xamarin.iOS.

Из того, что я собираю в документации Xamarin (которая всегда кажется основанной на устаревших версиях фреймворка), мне нужно привязать данные (но не отображать их) к UICollectionViewCell с использованием шаблона KVC.

Это лучший метод вызова SetValueForKey(NSObject object, NString key) в моем методе UpdateCell (ПРИМЕЧАНИЕ: Я изменил Params порождающим):

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 
    } 
} 

И MyClass.cs (опять же, не это настоящее имя, но для иллюстрации)

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

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

    // more props omitted for brevity 
} 

Является ли проблема, что объект, который я пытаюсь связать не наследует NSObject и, следовательно, не будет работать с SetValueForKey.

Я надеюсь привязать объект к ячейке, коснуться ячейки, получить данные, привязанные к ячейке, и, наконец, сделать вызов REST с использованием связанных данных.

Причина этого? Ну, я хочу, чтобы свойство MyClass «Name» отображалось на метке UICollectionViewCell, а «Id» - для вызова REST, но не отображался для пользователя. В настоящее время на этикетке появляется TapGesture, но я не могу получить значение для myClassObject.Id и, следовательно, не могу сделать веб-звонок!

UITapGestureRecognizer подключается к UICollectionView в моем UICollectionViewController - код не требуется для охвата вопроса) и corrently запускает событие, но требует, чтобы значение для ключа «BoundMyClassObject» или myClassObject.Id для POST в формате JSON ...

Имеют смысл?

Пожалуйста, помогите мне, поскольку в документации и форумах Xamarin имеется очень мало информации.

Все самое лучшее,

Джон

EDIT

Как @AdamKemp указывает в пост здесь SetValueForKey предназначается для NSObject с.

Так я переработан код в MyClass.cs следующим

[Register ("MyClass)] общественный класс Мой класс: NSObject { общественного MyClass() {}

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 
} 

Однако, когда я звоните SetValueForKey в моем UpdateCell метод

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

    this.SetValueForKey(myClassObject, "MyClassObject"); 

я сталкиваюсь следующее сообщение об ошибке

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

ответ

1

Okay,

я добавил следующие свойства моего UICollectionViewCell класса:

[Export("Id")] 
NSNumber Id { get; set; } 
[Export("Name")] 
NSString Name { get; set; } 

А также изменяет аргументы передаются SetValueForKey

this.SetValueForKey(new NSNumber(7), 
        new NSString("Id")); 

Затем он правильно присвоит значение 7 свойство этого UICollectionViewCell. Обратите внимание, что ваши свойства должны ВСЕ быть украшены [Export].

Фактически MyClass.cs больше не требуется - если вы поместите свойства в пользовательский UICollectionViewCell и вызовите SetValueForKey для их инициализации.

Они могут быть считаны в любом месте с помощью

NSNumber instanceID = (NSNumber)cell.ValueForKey(new NSString("Id")); 

Затем вы можете использовать данные, полученные из этого вызова и перейти к слою доступа к данным по мере необходимости.

В качестве метода в стороне метод SetValueForKey ожидает в качестве первого аргумента NSObject (или его ребенка). Досадно NSDate может быть болью, так что я сделал метод расширения для преобразования C# DateTime в NSDate для легких связывания данных:

public static NSDate DateTimeToNSDate(DateTime date) 
{ 
    return NSDate.FromTimeIntervalSinceReferenceDate((date - (new DateTime(2001, 1, 1, 0, 0, 0))).TotalSeconds); 
} 

public static DateTime NSDateToDateTime(NSDate date) 
{ 
    return (new DateTime(2001, 1, 1, 0, 0, 0)).AddSeconds(date.SecondsSinceReferenceDate); 
} 

Наконец, см this Xamarin учебника для получения дополнительной информации о связывании данных.

Надеюсь, это поможет людям в будущем! (Привет, будущие люди - возникла особенность?)

Смежные вопросы