2

我已经在这个主题上杀死了一天,但仍然不知道如何以正确的方式完成。

NSOutlineView用来显示文件系统层次结构。对于第一列中的每一行,我需要显示复选框、关联的图标和文件或目录的名称。由于没有标准的方法来做到这一点,我已经NSTextFieldCell使用 SourceView 和 PhotoSearch 示例进行了子类化,value在 IB 中绑定到name我的树项类的属性NSTreeController。我正在使用drawWithFrame:inView:覆盖来绘制复选框和图像,将文本绘制转发到super. 我还使用trackMouse:inRect:ofView:untilMouseUp:覆盖来处理复选框交互。

一切都很好,直到我注意到一旦我在自定义单元格中按下鼠标按钮,单元格对象就会被复制,copyWithZone:然后这个临时对象会被发送一条trackMouse:inRect:ofView:untilMouseUp:消息,从而无法修改驻留在看法。

由于问题主题是关于绑定的,我认为这可能是答案,但我完全不明白我应该如何连接所有这些混乱以按预期运行。试过这个:

[[[treeView outlineTableColumn] dataCell] bind:@"state"
                                      toObject:treeController
                                   withKeyPath:@"selection.state"
                                       options:nil];

但根本没有成功。好像我没有得到它。

这可能是我采取的完全错误的方式吗?您能否提出更好的替代方案或任何链接以供进一步阅读?


UPD 1/21/11:我也试过这个:

[[[treeView outlineTableColumn] dataCell] bind:@"state"
                                      toObject:treeController
                                   withKeyPath:@"arrangedObjects.state"
                                       options:nil];

但不断收到类似“[<_NSControllerTreeProxy 0x...> valueForUndefinedKey:]:此类与键状态的键值编码不兼容”之类的错误。和类似的。

4

2 回答 2

2

您绑定表(或大纲)列的值,而不是单个数据单元格的状态。数据单元格的对象值设置为当前行/列的值,然后绘制,这样您就不会无缘无故地创建数千个(或数百万个?)单元格。

此外,您需要树或数组控制器的排列对象,而不是其选择。

将列的值绑定到树控制器的arrangedObjects作为控制器键,“状态”作为IB中的模型键路径;或@"arrangedObjects.state" 在上面的代码中。

于 2011-01-20T21:47:24.970 回答
1

value好的,我已经设法通过将列绑定到(在 IB 中)并覆盖单元格来完成我需要的操作arrangedObject,使其看起来像:selfsetObjectValue:

- (void) setObjectValue:(id)value
{
    if ([value isMemberOfClass:[MyNodeClass class]])
    {
        [super setObjectValue:[value name]];
        [self setIcon:[value icon]];
        [self setState:[value state]];
    }
    else
    {
        if (!value)
        {
            [self setIcon:nil];
            [self setState:NSOffState];
        }
        [super setObjectValue:value];
    }
}

实际state更改是在另一个类中执行的,将其方法连接到selector我调用的单元(在 IB 中)

[NSApp sendAction:[self action] to:[self target] from:[self controlView]];

从细胞的trackMouse:inRect:ofView:untilMouseUp:. 这另一个类的方法如下所示:

- (IBAction) itemChecked:(id)sender
{
    MyNodeClass* node = [[sender itemAtRow:[sender clickedRow]] representedObject];
    if (node)
    {
        [node setState:[node state] == NSOnState ? NSOffState : NSOnState];
    }
}
于 2011-01-24T13:01:51.697 回答