如何自动选择插入到 NSOutlineView 中的项目核心数据
我有一个 NSTreeController 绑定了一个绑定到实体的 NSArrayController ,并将树绑定到了 NSOutlineView 。现在,当单击“添加”按钮时,我想向 TreeController 添加一个新实体,选择该实体,然后突出显示它以进行编辑。如果我调用 [arrayController add] ,插入是异步的,我无法知道新对象是哪个,因为大纲视图不会自动选择新行。所以我只能以编程方式插入新实体。因此,addButton
在outlineViewController
上调用createNewGroup
(见下文)。
同样,插入新实体似乎不是一个同步过程。我无法在 currentObject = [NSEntityDescription...
之后的下一行的 NSOutlineView
中找到它。我在重新加载数据后确实尝试过。所以我只能观察数组控制器中的值变化。大多数情况下,这种方法有效,但有时却行不通。这是处理此类事情的正确方法吗?
- (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;
}
}
}
}
}
I have an NSTreeController
bound an NSArrayController
bound to an entity and the tree bound to an NSOutlineView
. Now, when an "add" button is clicked, I would like to add a new entity to the treeController
, select the entity, and highlight it for editing. If I call [arrayController add]
, the insertion is asynchronous and I have no way of knowing which the new object is since the outline view does not select new rows automatically. So I am left with inserting the new Entity programatically. So addButton
calls createNewGroup
on a outlineViewController
(see below).
Again, inserting a new entity does not seem to be a synchronous process. I can't locate it in the NSOutlineView
in the next line after currentObject = [NSEntityDescription...
. And I did try after reloading the data. So I am left with observing the value changes in the array controller. This sort of works, most of the time, but occasionally it does not. Is this the right approach to this sort of thing?
- (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;
}
}
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果你使用 NSTreeController (的子类)来为你的outlineView提供内容,那就非常简单了。您可以在代码或 Interface Builder 中创建一个按钮,并将目标绑定到
insert:
以添加元素或设置remove:
以删除它。在代码中,它看起来像这样:选择新对象是由树控制器处理的。再次,在代码中:
在 IB 中,这是一个您需要选中的复选框。哦,还有
addChild:
。让绑定发挥其魔力。If you use (a subclass of) NSTreeController to provide the content for you outlineView, it is very simple. You create a button, either in code or in Interface Builder, and set bind the target to
insert:
to add an element orremove:
to delete it. In code it would look like this:Selecting the new object is handled by the treeController. Again, in code:
In IB, it's a checkbox that you need to check. Oh, there's also
addChild:
. Let the bindings do their magic.