Вопрос

Я использую NSOutlineView без NSTreeController и реализовал свой собственный источник данных.Каков наилучший способ выбора товара?NSOutlineView поддержка уже есть expandItem: и collapseItem:.И мне не хватает удобного метода, такого как `SelectItem:.Как я могу сделать это программно ?

Спасибо.

Это было полезно?

Решение

Не забудьте заглянуть в суперклассы, если вы не можете что-то найти.В этом случае один из необходимых вам методов поступает из NSTableView, который является непосредственным суперклассом NSOutlineView.

Решение состоит в том, чтобы получите индекс строки для элемента, используя rowForItem:, и если оно не равно -1 (элемент не виден / не найден), создайте набор индексов с его помощью [NSIndexSet indexSetWithIndex:] и передайте этот индекс, установленный в тот самый selectRowIndexes:byExtendingSelection: способ.

Другие советы

Вот как я в конце концов оказался.Предложения и исправления всегда приветствуются.

@implementation NSOutlineView (Additions)

- (void)expandParentsOfItem:(id)item {
    while (item != nil) {
        id parent = [self parentForItem: item];
        if (![self isExpandable: parent])
            break;
        if (![self isItemExpanded: parent])
            [self expandItem: parent];
        item = parent;
    }
}

- (void)selectItem:(id)item {
    NSInteger itemIndex = [self rowForItem:item];
    if (itemIndex < 0) {
        [self expandParentsOfItem: item];
        itemIndex = [self rowForItem:item];
        if (itemIndex < 0)
            return;
    }

    [self selectRowIndexes: [NSIndexSet indexSetWithIndex: itemIndex] byExtendingSelection: NO];
}
@end

Нет, здесь нет никакого selectItem: метод, но есть rowForItem: способ.Если вы объедините это с советом Питера об использовании selectRowIndexes:byExtendingSelection: вышесказанное говорит о том, что у вас должна быть вся необходимая информация.

Если бы вы действительно хотели иметь метод выбора элемента, который я бы рекомендовал вызвать setSelectedItem: ради согласованности вы могли бы написать что-то подобное в категории на NSOutlineView

- (void)setSelectedItem:(id)item {
    NSInteger itemIndex = [self rowForItem:item];
    if (itemIndex < 0) {
        // You need to decide what happens if the item doesn't exist
        return;
    }

    [self selectRowIndexes:[NSIndexSet indexSetWithIndex:itemIndex] byExtendingSelection:NO];
}

Я понятия не имею, действительно ли этот код работает;Я просто набросал это, чтобы проиллюстрировать концепцию.

Вот фрагмент кода, который я использовал для программного выбора элемента в PXSourceList.

SourceList - это обычный объект PXSouceList, и я хотел выбрать второй элемент в первой группе схемы.

    NSInteger itemRow = [sourceList rowForItem:[[(SourceListItem *)[sourceListItems objectAtIndex:0] children] objectAtIndex:1]];
    [sourceList selectRowIndexes:[NSIndexSet indexSetWithIndex:itemRow] byExtendingSelection:YES];

Если вы еще не знаете, PXSourceList - отличная замена NSOutlineView, если вы ищете схемы в стиле itunes / mail.Возьми это здесь:PxSourceList Список источников

Это старый вопрос, но ситуация все та же.Поскольку был запрос на версию swift, вот мое мнение.Я не нашел приемлемого ответа, который работал бы для меня, поскольку я думаю, что вы должны напрямую взаимодействовать со своим классом источника данных, а не расширять NSOutlineView.Досадно, что схема не найдет строк, если они не будут расширены, поэтому проще использовать ваш источник данных.В моем случае я обнаружил, что вам нужно развернуть родительские элементы ваших элементов в обратном порядке, чтобы начать с верхнего уровня и продвигаться к фактическому элементу, который вы пытаетесь расширить.Я чувствую, что это должно быть встроено, но если я чего-то не упустил - это не так.

В этом примере FileItem - это класс элемента моей коллекции источников данных.Он содержит свойство "parent", которое должно быть допустимым, если оно является частью отображаемой иерархии.

func selectItem(_ item: FileItem, byExtendingSelection: Bool = false) {
    guard let outlineView = outlineView else { return }

    var itemIndex: Int = outlineView.row(forItem: item)

    if itemIndex < 0 {
        var parent: FileItem? = item

        var parents = [FileItem?]()
        while parent != nil {
            parents.append(parent)
            parent = parent?.parent
        }

        let reversedTree = parents.compactMap({$0}).reversed()

        for level in reversedTree {
            outlineView.expandItem(level, expandChildren: false)
        }

        itemIndex = outlineView.row(forItem: item)
        if itemIndex < 0 {
            print("Didn't find", item)
            return
        }
    }

    print("Expanding row", itemIndex)

    outlineView.selectRowIndexes(IndexSet(integer: itemIndex), byExtendingSelection: byExtendingSelection)
    outlineView.scrollRowToVisible(itemIndex)
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top