在Xamarin中绑定多维数组

时间:2015-02-23 13:02:21

标签: xamarin.ios xamarin

我正在尝试绑定一个属性,我知道这是一个(多维)NSArray持有NSArray个对象,而这些对象又包含NSObject的实例。我这样绑定了这个方法:

[Export ("options")]
NSObject[][] Options { get; set; }

当我构建我的绑定时,我在上面属性的生成类中得到以下错误。

从生成的调用NSArray.FromNSObjects

(1) Argument `#1` cannot convert 'Foundation.NSObject[][]' expression to type 'Foundation.NSObject[]'.
(2) Error CS1502: The best overloaded method match for `Foundation.NSArray.FromNSObjects(params Foundation.NSObject[])' has some invalid arguments (CS1502)

从生成的调用NSArray.ArrayFromHandle<Foundation.NSObject[]>

(1) Error CS0311: The type `Foundation.NSObject[]' cannot be used as type parameter `T' in the generic type or method `Foundation.NSArray.ArrayFromHandle<T>(System.IntPtr)'. There is no implicit reference conversion from `Foundation.NSObject[]' to `ObjCRuntime.INativeObject' (CS0311)

错误一直指的是编译器无法在Foundation.NSObject[][]Foundation.NSObject[]之间进行转换。我不明白为什么会出现问题,NSArrayNSObject的子类,为什么不能将第二个数组维度视为NSObject

(我知道我有其他选择,例如将选项绑定为NSObject[],或只是NSObject,但我宁愿尽可能保持类型安全。)

1 个答案:

答案 0 :(得分:0)

我认为出现这个问题是因为方法FromNSObjectsArrayFromHandle无法处理多维数组的转换,但我并不完全确定。

我设法通过从绑定文件(ApiDefinition.cs)中删除Options的绑定并在部分类中手动绑定属性来解决此问题。

我写了两种方法来在多维NSArrayNSObject[][]之间进行转换。

    private NSArray NSArraysFromTwoDimentionalArray(NSObject[][] firstDimension) {
        NSMutableArray nsFirstDimension = new NSMutableArray ();

        foreach (NSObject[] secondDimention in firstDimension) {
            NSMutableArray nsSecondDimension = new NSMutableArray ();
            foreach (NSObject nsObj in secondDimention) {
                nsSecondDimension.Add (nsObj);
            }
            nsFirstDimension.Add (nsSecondDimension);
        }

        NSArray toReturn = (NSArray)nsFirstDimension.Copy ();

        nsFirstDimension.Dispose ();

        return toReturn;
    }

    private NSObject[][] TwoDimentionalArrayFromArrayOfNSArrays (NSArray[] nsFirstDimension) {
        NSObject[][] firstDimension = new NSObject[nsFirstDimension.Length][];

        int i = 0;
        foreach (NSArray nsSecondDimension in nsFirstDimension) {
            NSObject[] secondDimension = NSArray.ArrayFromHandle<NSObject> (nsSecondDimension.Handle);

            firstDimension[i] = secondDimension;
            i++;
        }

        return firstDimension;
    }

然后我使用上面的转换方法来实现我的绑定。

    public virtual NSObject[][] Options {
        [Export ("options")]
        get {

            NSArray[] firstDimension;
            if (IsDirectBinding) {
                firstDimension = NSArray.ArrayFromHandle<NSArray> (ApiDefinition.Messaging.IntPtr_objc_msgSend (this.Handle, Selector.GetHandle ("options")));
            } else {
                firstDimension = NSArray.ArrayFromHandle<NSArray> (ApiDefinition.Messaging.IntPtr_objc_msgSendSuper (this.SuperHandle, Selector.GetHandle ("options")));
            }

            return TwoDimentionalArrayFromArrayOfNSArrays (firstDimension);
        }


        [Export ("setOptions:")]
        set {
            if (value == null)
                throw new ArgumentNullException ("value");

            var multiNSArray = NSArraysFromTwoDimentionalArray (value);

            if (IsDirectBinding) {
                ApiDefinition.Messaging.void_objc_msgSend_IntPtr (this.Handle, Selector.GetHandle ("setOptions:"), multiNSArray.Handle);
            } else {
                ApiDefinition.Messaging.void_objc_msgSendSuper_IntPtr (this.SuperHandle, Selector.GetHandle ("setOptions:"), multiNSArray.Handle);
            }
            multiNSArray.Dispose ();

        }

    }