В Xamarin iOS EventArgs отсутствует первое свойство

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

В сгенерированном классе аргументов события отсутствует первый параметр.

Например:

[Protocol, Model]
[BaseType(typeof(NSObject))]
public interface TestDelegate
{
    // @required -(void)DidReceiveFrom:(NSString * _Nonnull)p1 withP2:(NSString * _Nonnull)p2 withP3:(NSString * _Nonnull)p3 withP4:(NSString * _Nonnull)p4;
    [Abstract]
    [Export("DidReceiveFrom:withP2:withP3:withP4:")]
    [EventArgs("DidReceiveFrom")]
    void DidReceiveFrom(string p1, string p2, string p3, string p4);

Затем сгенерированный класс EventArgs становится:

//
// EventArgs classes
//
public partial class DidReceiveFromEventArgs : EventArgs {
    public DidReceiveFromEventArgs (string p2, string p3, string p4)
    {
        this.p2 = p2;
        this.p3 = p3;
        this.p4 = p4;
    }
    public string p2 { get; set; }
    public string p3 { get; set; }
    public string p4 { get; set; }
}

Так что определенно отсутствует свойство p1. Как избежать такого поведения?


person awattar    schedule 31.03.2017    source источник


Ответы (2)


Я предполагаю, что вы используете инструмент objective sharpie для создания кода C# для Objective C API.

Если это так, то в основном вам нужно помнить, что это вспомогательный инструмент, но не 100% гарантия, что он получит правильный код C# для вас.

Независимо от этого, самый простой способ исправить это — отредактировать код C# вручную и добавить этот параметр, если вы его пропустили.

Вы не показываете свой код C# для файла TestDelegate. Может быть, у вас есть первый параметр в качестве отправителя, а затем все 3 других параметра в качестве аргументов события?

Если это так, закомментируйте атрибут [EventArgs("DidReceiveFrom")] в C# API и перекомпилируйте привязки.

person Alex Sorokoletov    schedule 01.04.2017
comment
Это проект привязки iOS, поэтому код делегата C# будет сгенерирован из приведенного выше примера кода. Нет места, где я могу отредактировать делегата, чтобы использовать или не использовать отправителя в качестве первого параметра. Я просто хочу использовать события С# и иметь все параметры в классе EventArgs, тогда отправитель должен содержать реальный объект отправителя, а не свойство первого аргумента события. - person awattar; 01.04.2017
comment
@awattar Вы написали этот код C # или сгенерировали его из файла objc? - person Alex Sorokoletov; 01.04.2017
comment
Код был сгенерирован с помощью инструмента Sharpie, но я добавил атрибут EventArgs, потому что хочу использовать события C# вместо сильного или слабого делегата. Все работает нормально, за исключением того, что первое свойство, сгенерированное из метода делегата, отсутствует в сгенерированном классом библиотеки привязки EventArgs. - person awattar; 01.04.2017
comment
@awattar, если вы написали EventArgs, почему вы не добавили p1 в определение класса? - person Alex Sorokoletov; 02.04.2017
comment
Я написал атрибут EventArgs только в методе делегата, сгенерированном маркером, в проекте привязки. Затем проект привязки генерирует неправильный класс EventArgs с отсутствующим первым свойством. - person awattar; 02.04.2017

Согласно документации Xamarin, это поведение по умолчанию:

Для событий, которые принимают более одного параметра (в Objective-C соглашение заключается в том, что первый параметр в классе делегата является экземпляром объекта-отправителя), вы должны указать имя, которое вы хотели бы использовать для сгенерированного класса EventArgs. Это делается с помощью атрибута EventArgs в объявлении метода в вашем классе Model.

https://developer.xamarin.com/guides/cross-platform/macios/binding/binding-types-reference/#EventArgsAttribute

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

person awattar    schedule 03.04.2017