2012-01-12 1 views
1

Я пытаюсь реализовать источник данных для NSOutlineView. Проблема в том, что я не знаю, какой тип объекта должен возвращаться с outlineView:child:ofItem:.Реализация NSOutlineViewDataSource с использованием MonoMac

Текущий код выглядит следующим образом:

[Export("outlineView:child:ofItem:")] 
public NSObject childOfItem(NSOutlineView outline, int child, NSObject item) 
{ 
    return new MyItem(); 
} 

С MyItem:

public class MyItem : NSObject 
{} 

EDIT: С помощью этого кода я получаю InvalidCastException только после возвращения MyItem.

ответ

1

Если вы унаследовали новый тип из NSOutlineViewDataSource, то вы не должны реэкспорт его outlineView:child:ofItem: селектор на свой собственный метод. Вместо этого вы должны переопределить метод GetChild, который уже экспортирует этот селектор, например.

public overrride NSObject GetChild (NSOutlineView outlineView, int childIndex, NSObject ofItem) 
{ 
    return new MyItem(); 
} 

Примечание: это не может помочь, так как я не пробовал (я в основном делать MonoTouch вещи), но рассмотреть другие селекторы вы можете быть переосмысление/экспорт в приложении (чтобы увидеть, если вы не должны быть переопределение - их от базового класса, который вы наследуете).

+0

Большое спасибо, это было решение –

0

Считаете ли вы использование NSTreeController? Он помогает управлять контурным представлением для вас и очень удобен. NSTreeController использует класс NSTreeNode для представления узлов в виде схемы, а каждый NSTreeNode имеет метод representedObject, который позволяет вам перейти к объекту модели.

В любом случае, если вы не хотите использовать NSTreeController или NSTreeNode, вы можете просто вернуть объект модели напрямую. Вот пример кода Objective-C из руководства Apple.

@implementation DataSource 
// Data Source methods 

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item { 

    return (item == nil) ? 1 : [item numberOfChildren]; 
} 


- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item { 
    return (item == nil) ? YES : ([item numberOfChildren] != -1); 
} 


- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item { 

    return (item == nil) ? [FileSystemItem rootItem] : [(FileSystemItem *)item childAtIndex:index]; 
} 


- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item { 
    return (item == nil) ? @"/" : [item relativePath]; 
} 

@end 


@interface FileSystemItem : NSObject 
{ 
    NSString *relativePath; 
    FileSystemItem *parent; 
    NSMutableArray *children; 
} 

+ (FileSystemItem *)rootItem; 
- (NSInteger)numberOfChildren;// Returns -1 for leaf nodes 
- (FileSystemItem *)childAtIndex:(NSUInteger)n; // Invalid to call on leaf nodes 
- (NSString *)fullPath; 
- (NSString *)relativePath; 

@end 


@implementation FileSystemItem 

static FileSystemItem *rootItem = nil; 
static NSMutableArray *leafNode = nil; 

+ (void)initialize { 
    if (self == [FileSystemItem class]) { 
     leafNode = [[NSMutableArray alloc] init]; 
    } 
} 

- (id)initWithPath:(NSString *)path parent:(FileSystemItem *)parentItem { 
    self = [super init]; 
    if (self) { 
     relativePath = [[path lastPathComponent] copy]; 
     parent = parentItem; 
     } 
    return self; 
} 


+ (FileSystemItem *)rootItem { 
    if (rootItem == nil) { 
     rootItem = [[FileSystemItem alloc] initWithPath:@"/" parent:nil]; 
    } 
    return rootItem; 
} 


// Creates, caches, and returns the array of children 
// Loads children incrementally 
- (NSArray *)children { 

    if (children == nil) { 
     NSFileManager *fileManager = [NSFileManager defaultManager]; 
     NSString *fullPath = [self fullPath]; 
     BOOL isDir, valid; 

     valid = [fileManager fileExistsAtPath:fullPath isDirectory:&isDir]; 

     if (valid && isDir) { 
      NSArray *array = [fileManager contentsOfDirectoryAtPath:fullPath error:NULL]; 

      NSUInteger numChildren, i; 

      numChildren = [array count]; 
      children = [[NSMutableArray alloc] initWithCapacity:numChildren]; 

      for (i = 0; i < numChildren; i++) 
      { 
       FileSystemItem *newChild = [[FileSystemItem alloc] 
            initWithPath:[array objectAtIndex:i] parent:self]; 
       [children addObject:newChild]; 
       [newChild release]; 
      } 
     } 
     else { 
      children = leafNode; 
     } 
    } 
    return children; 
} 


- (NSString *)relativePath { 
    return relativePath; 
} 


- (NSString *)fullPath { 
    // If no parent, return our own relative path 
    if (parent == nil) { 
     return relativePath; 
    } 

    // recurse up the hierarchy, prepending each parent’s path 
    return [[parent fullPath] stringByAppendingPathComponent:relativePath]; 
} 


- (FileSystemItem *)childAtIndex:(NSUInteger)n { 
    return [[self children] objectAtIndex:n]; 
} 


- (NSInteger)numberOfChildren { 
    NSArray *tmp = [self children]; 
    return (tmp == leafNode) ? (-1) : [tmp count]; 
} 


- (void)dealloc { 
    if (children != leafNode) { 
     [children release]; 
    } 
    [relativePath release]; 
    [super dealloc]; 
} 

@end 

Это не MonoMac, но должна быть той же идеей.

+0

Я понимаю, что вы говорите, вы также говорите, что я могу напрямую вернуть объект модели. Когда я это делаю, я получаю InvalidCastException, поэтому я думаю, что это проблема, характерная для MonoMac. Я попробую предложение TreeController, хотя, но я не думаю, что это поможет –