Привязка одного NSCell к нескольким значениям - PullRequest
2 голосов
/ 20 января 2011

Я уже убил день на эту тему и до сих пор не знаю, как это можно сделать правильно.

Я использую 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:]: этот класс не совместим со значением ключа для кодирования состояния ключа». и аналогичные.

Ответы [ 2 ]

2 голосов
/ 21 января 2011

Вы связываете значение столбца таблицы (или контура), а не состояние отдельной ячейки данных. Значение объекта ячейки данных устанавливается равным значению текущей строки / столбца, а затем отрисовывается, чтобы у вас не было потенциально тысяч (или миллионов?) Ячеек, созданных без уважительной причины.

Далее, вы хотите, чтобы дерево или контроллер массива упорядочивали объекты , а не его выбор.

Привязать значение столбца к agedObjects контроллера дерева в качестве ключа контроллера и "state" в качестве пути ключа модели в IB; или @ "agedObjects.state "в коде, как указано выше.

1 голос
/ 24 января 2011

Хорошо, мне удалось сделать то, что мне нужно, привязав столбцы value к arrangedObject 'self (в 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];
    }
}
...