简体   繁体   English

如何将NSTreeController,NSOutlineView和Core Data与“隐形”根项一起使用?

[英]How do I use NSTreeController, NSOutlineView and Core Data with an “invisible” root item?

I have a Core Data model which consists of a simple tree of a particular entity, which has two relationships, parent and children . 我有一个核心数据模型,它由一个特定实体的简单树组成,它有两个关系, parentchildren I have an NSTreeController managing the model, with an NSOutlineView bound to the NSTreeController . 我有一个管理模型的NSTreeControllerNSOutlineView绑定到NSTreeController

My problem is that I need a single root object, but this should not display in the outline view, only its children should be displayed at the top level of the outline view. 我的问题是我需要一个根对象,但是这不应该显示在大纲视图中,只有它的子项应该显示在大纲视图的顶层。 If I set the fetch predicate of the NSTreeController in Interface Builder to parent == nil , everything works fine except the root item is visible as the top level item in the outline view. 如果我将Interface Builder中NSTreeController的fetch谓词设置为parent == nil ,则一切正常,但根项目在大纲视图中作为顶级项目可见。

My entity has an attribute, isRootItem , that is true for the root item only. 我的实体有一个属性isRootItem ,仅对根项有效。

My model looks like this: 我的模型看起来像这样:

Node 1
|
+-Node 2
  |   |
  |   +-Node 5
  |
  Node 3
  |
  Node 4

The outline view should look like this: 大纲视图应如下所示:

大纲视图图像
(source: menumachine.com ) (来源: menumachine.com

I need to display Nodes 2, 3 and 4 at the top level of the outline view (Node 1 should not be visible), but still have their parent be "Node 1". 我需要在大纲视图的顶层显示节点2,3和4(节点1不应该是可见的),但是它们的父节点仍然是“节点1”。 Node 1 has a value of YES for isRootItem and all the others have NO . 对于isRootItem ,节点1的值为YES ,而其他所有节点都为NO

If I set the fetch predicate of the tree controller to parent.isRootItem == 1 , this displays the tree correctly, but as soon as I add a new item to the top level it fails because the tree controller does not assign the "invisible" root item as the parent of the new item. 如果我将树控制器的fetch谓词设置为parent.isRootItem == 1parent.isRootItem == 1正确显示树,但是一旦我将新项添加到顶层,它就会失败,因为树控制器没有指定“不可见”根项目作为新项目的父项。

Is there a way to get the NSTreeController / NSOutlineView combination to work in this situation? 有没有办法让NSTreeController / NSOutlineView组合在这种情况下工作?

What I've ended up doing is subclassing NSTreeController and overriding -insertObject:atArrangedObjectIndexPath: to directly set the parent to my root object if the object being inserted is being inserted at the top level of the tree. 我最终做的是-insertObject:atArrangedObjectIndexPath: NSTreeController并重写-insertObject:atArrangedObjectIndexPath:如果正在插入的对象插入树的顶层,则直接将父对象设置为我的根对象。 This seems to work reliably. 这似乎可靠地工作。

Obviously more work would be needed to handle moving items and inserting multiple items but this seems to be the best way forward. 显然,处理移动物品和插入多个物品需要更多的工作,但这似乎是最好的前进方式。

- (void)insertObject:(id)object atArrangedObjectIndexPath:(NSIndexPath *)indexPath
{
    NodeObject* item = (NodeObject*)object;
    //only add the parent if this item is at the top level of the tree in the outline view
    if([indexPath length] == 1)
    {
        //fetch the root item
        NSEntityDescription* entity = [NSEntityDescription entityForName:@"NodeObject" inManagedObjectContext:[self managedObjectContext]];
        NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] init]; //I'm using GC so this is not a leak
        [fetchRequest setEntity:entity];
        NSPredicate* predicate = [NSPredicate predicateWithFormat:@"isRootItem == 1"];
        [fetchRequest setPredicate:predicate];

        NSError* error;
        NSArray* managedObjects = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];

        if(!managedObjects)
        {
            [NSException raise:@"MyException" format:@"Error occurred during fetch: %@",error];
        }

        NodeObject* rootItem = nil;
        if([managedObjects count])
        {
            rootItem = [managedObjects objectAtIndex:0];
        }
        //set the item's parent to be the root item
        item.parent = rootItem;
    }
    [super insertObject:object atArrangedObjectIndexPath:indexPath];
    //this method just sorts the child objects in the tree so they maintain their order
    [self updateSortOrderOfModelObjects];
}

Have you tried binding to the NSTreeController's addChild: method? 您是否尝试过绑定到NSTreeController的addChild:方法?

It's because of times like this that I don't use NSTreeController. 因为这样的时候我不使用NSTreeController。

You could do away with it and implement the delegate methods of the Source view which will give you much better control about what you display. 您可以取消它并实现Source视图的委托方法,这将使您更好地控制您显示的内容。 It isn't too much extra work and might be easier than banging you head trying to get the NSTreeController to work how you want it to. 这不是太多额外的工作,可能比敲打你试图让NSTreeController以你想要的方式工作更容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 NSOutlineView 与 NSTreeController 绑定与核心数据 - NSOutlineView with NSTreeController bindings with core data NSOutlineView +核心数据,无需使用NSTreeController - NSOutlineView + Core Data without using NSTreeController 如何在不使用 NSTreeController 的情况下获取 NSOutlineView 的选定项目? - How to get selected item of NSOutlineView without using NSTreeController? 如何动态更新NSTreeController和NSOutlineView? - How to dynamically update an NSTreeController and NSOutlineView? 如何自动选择插入的项目以及NSOutlineView和Core Data - How to automatically select an item inserted into and NSOutlineView & Core Data 如何在由NSTreeController填充的NSOutlineView中锁定父行 - How to lock parent rows in NSOutlineView populated by NSTreeController 如何在没有NSTreeController的情况下在NSOutlineView中选择项目? - How to select items in NSOutlineView without NSTreeController? 使用NSTreeController,更改模型数组时是否必须手动重新加载NSOutlineView? - With NSTreeController, do I have to manually reload an NSOutlineView when changing the model array? 如何将NSOutlineView与多个核心数据实体作为组一起使用 - How to use NSOutlineView with multiple core data entities as groups NSTreeController:如何找到节点的父级? - NSTreeController: how do I find the parent of a node?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM