将单个 NSCell 绑定到多个值

发布于 2024-10-12 18:01:30 字数 1427 浏览 6 评论 0原文

我已经在这个主题上浪费了一天的时间,但仍然不知道如何以正确的方式完成这件事。

我正在使用 NSOutlineView 来显示文件系统层次结构。对于第一列中的每一行,我需要显示复选框、关联的图标以及文件或目录的名称。由于没有标准方法来实现此目的,因此我使用 SourceView 和 PhotoSearch 示例对 NSTextFieldCell 进行子类化,将 IB 中的 value 绑定到 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:]:此类不符合键值编码的错误”对于关键状态。”和类似的。

I've already killed a day on this subject and still got no idea on how could this be done in a correct way.

I'm using NSOutlineView to display filesystem hierarchy. For each row in the first column I need to display checkbox, associated icon and name of the file or directory. Since there's no standard way to make this, I've subclassed NSTextFieldCell using both SourceView and PhotoSearch examples, binding value in IB to name property of my tree item class though NSTreeController. I'm using drawWithFrame:inView: override to paint checkbox and image, forwarding text drawing to super. I'm also using trackMouse:inRect:ofView:untilMouseUp: override to handle checkbox interaction.

Everything was fine up until I noticed that once I press mouse button down inside my custom cell, cell object is being copied with copyWithZone: and this temporary object is then being sent a trackMouse:inRect:ofView:untilMouseUp: message, making it impossible to modify check state of the original cell residing in the view.

Since the question subject is about binding, I thought this might be the answer, but I totally don't get how should I connect all this mess to function as expected. Tried this:

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

but didn't succeed at all. Seems like I'm not getting it.

May this be a completely wrong way I've taken? Could you suggest a better alternative or any links for further reading?


UPD 1/21/11: I've also tried this:

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

but kept getting errors like "[<_NSControllerTreeProxy 0x...> valueForUndefinedKey:]: this class is not key value coding-compliant for the key state." and similar.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

来日方长 2024-10-19 18:01:30

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

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

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

You bind a table (or outline) column's value, not an individual data cell's state. The data cell's object value is set to the current row/col's value then drawn so you don't have potentially thousands (or millions?) of cells created for no good reason.

Further, you want the tree or array controller's arrangedObjects, not its selection.

Bind the column's value to the tree controller's arrangedObjects as the controller key, and "state" as the model key path in IB; or @"arrangedObjects.state" in code as above.

肥爪爪 2024-10-19 18:01:30

好的,我已经成功地通过将列的 value 绑定到 arrangedObjectself (在 IB 中)并覆盖单元格的 来完成我需要的操作>setObjectValue:,这样它看起来像:

- (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];
    }
}

Okay, I've managed to do what I needed by binding columns's value to arrangedObject's self (in IB) and overriding cell's setObjectValue: so that it looks like:

- (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];
    }
}

Actual state change is performed within another class, connecting its method to cell's selector (in IB) which I call using

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

from cell's trackMouse:inRect:ofView:untilMouseUp:. This another class'es method looks like this:

- (IBAction) itemChecked:(id)sender
{
    MyNodeClass* node = [[sender itemAtRow:[sender clickedRow]] representedObject];
    if (node)
    {
        [node setState:[node state] == NSOnState ? NSOffState : NSOnState];
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文