0

我有一个NSTreeController绑定NSArrayController到一个实体的绑定和一个绑定到一个NSOutlineView. 现在,当单击“添加”按钮时,我想向 中添加一个新实体treeController,选择该实体,然后突出显示它以进行编辑。如果我调用[arrayController add],则插入是异步的,我无法知道新对象是哪个,因为大纲视图不会自动选择新行。所以我只能以编程方式插入新实体。所以addButton调用createNewGroupa outlineViewController(见下文)。

同样,插入新实体似乎不是一个同步过程。我无法在NSOutlineView之后的下一行中找到它currentObject = [NSEntityDescription...。我在重新加载数据后确实尝试过。所以我只剩下观察数组控制器中的值变化了。这种工作,大部分时间,但偶尔不会。这是处理这类事情的正确方法吗?

- (void) createNewGroup:(id)sender {
    NSInteger row = [myOutlineView selectedRow];
    if(row == -1) {
        [groupsController addObserver:self 
                           forKeyPath:IR_GROUPS_KEYPATH 
                              options:NSKeyValueObservingOptionInitial 
                              context:IR_GROUPS_CONTEXT];
        currentObject = [NSEntityDescription insertNewObjectForEntityForName:@"Group" 
                                                      inManagedObjectContext:appDelegate.managedObjectContext];
        return;
    }
    if([myOutlineView levelForRow:row] != 0) return;
    [subGroupsController addObserver:self 
                          forKeyPath:IR_GROUPS_KEYPATH 
                             options:NSKeyValueObservingOptionInitial 
                             context:IR_SUBGROUPS_CONTEXT];
    NSManagedObject *parent = [[myOutlineView itemAtRow:row] representedObject];
    currentObject = [NSEntityDescription insertNewObjectForEntityForName:@"Group" 
                                                            inManagedObjectContext:appDelegate.managedObjectContext];
    [currentObject setValue:parent forKey:@"parent"];
}

- (void) observeValueForKeyPath:(NSString *)keyPath 
                       ofObject:(id)object 
                         change:(NSDictionary *)change 
                        context:(void *)context {

    if([keyPath isEqualToString:IR_GROUPS_KEYPATH]) {
        if(currentObject == nil) return;
        [myOutlineView noteNumberOfRowsChanged];
        NSString *ctx = (NSString *) context;
        if([ctx isEqualToString:IR_GROUPS_CONTEXT]) {

            NSInteger length = [myOutlineView numberOfRows];
            NSInteger index;
            for(index = 0; index < length; index++) {
                id item = [myOutlineView itemAtRow:index];
                if(currentObject == [item representedObject]) {
                    // We found the new object:
                    NSIndexSet *indices = [NSIndexSet indexSetWithIndex:index];
                    [myOutlineView selectRowIndexes:indices byExtendingSelection:NO];
                    [myOutlineView editColumn:0 row:index withEvent:nil select:YES];
                    currentObject = nil;
                    return;
                }
            }
            //[groupsController removeObserver:self forKeyPath:nil];

        } else if([ctx isEqualToString:IR_SUBGROUPS_CONTEXT]) {
            NSTreeNode *parent = [myOutlineView itemAtRow:[myOutlineView selectedRow]];
            [myOutlineView expandItem:parent];
            NSInteger length = [myOutlineView numberOfRows];
            NSInteger index;
            for(index = 0; index < length; index++) {
                id item = [myOutlineView itemAtRow:index];
                if(currentObject == [item representedObject]) {
                    NSIndexSet *indices = [NSIndexSet indexSetWithIndex:index];
                    [myOutlineView selectRowIndexes:indices byExtendingSelection:NO];
                    [myOutlineView editColumn:0 row:index withEvent:nil select:YES];
                    currentObject = nil;
                    return;
                }
            }
        }
    }
}
4

1 回答 1

1

如果你使用(一个子类)NSTreeController 来为你提供outlineView 的内容,那就很简单了。您可以在代码中或在 Interface Builder 中创建一个按钮,并将绑定目标设置为添加或删除insert:元素。remove:在代码中它看起来像这样:

[aButton bind:NSTargetBinding 
     toObject:aController 
  withKeyPath:keyPathToTreeController
    options:[NSMutableDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES], NSConditionallySetsEnabledBindingOption,
                             @"insert:", NSSelectorNameBindingOption,
                             nil]];

选择新对象由 treeController 处理。同样,在代码中:

[aTreeController setSelectsInsertedObjects:YES];

在 IB 中,这是一个您需要选中的复选框。哦,还有addChild:。让绑定发挥他们的魔力。

于 2011-04-23T16:11:58.033 回答