简体   繁体   English

在NSOutlineView选择上获取NSTreeController数据

[英]Getting NSTreeController Data on NSOutlineView selection

I've built an NSOutlineView that gets dynamically updated data from an NSTreeController and that all works fine. 我建立了一个NSOutlineView ,它从NSTreeController获取动态更新的数据,并且一切正常。 What I can't seem to do is work backwards from there based on a user selection in the NSOutlineView. 我似乎无法做的是根据NSOutlineView中的用户选择从那里向后工作。

    var deviceStore = [TreeNode]()

is my backing datastore that is updated in real-time it is an array of Device Objects, which may )or may not) contain an array of Service objects as children. 是我的支持数据存储库,它是实时更新的,它是Device对象数组,可以(也可以不)包含Service对象数组作为子对象。

This all works. 所有这一切。 But when I select a row in the Outline View, I need to work my way back to the original object in the deviceStore -- or, at the very least, get the displayed data from the OutlineView so that I can walk the deviceStore to find the original item. 但是,当我在“大纲视图”中选择一行时,我需要返回到deviceStore中的原始对象,或者至少从“大纲视图”中获取显示的数据,以便我可以在deviceStore中查找原始项目。

What I've got is func outlineViewSelectionDidChange(_ notification: Notification) {} which is called when a selection is made, and I can, from that, extract the NSTreeController TreeNode via treeController.selectedNodes but from there, I am in the weeds. 我得到的是func outlineViewSelectionDidChange(_ notification: Notification) {} ,当做出选择时会调用它,我可以通过treeController.selectedNodes从中提取NSTreeController TreeNode,但是从那里,我就在杂草中。 The selectedNodes is the complete array of the selected Node, so if it's a child (leaf) node, it includes its parent node, and all its siblings. selectedNodes是所选节点的完整数组,因此,如果它是子(叶)节点,则它包括其父节点及其所有同级节点。

Give then Table shown here: 给然后表显示在这里: 轮廓视图

The selectedNodes array looks like this: selectedNodes数组如下所示:

<NSTreeControllerTreeNode: 0x6080000c4590>, child nodes {
    0:<NSTreeControllerTreeNode: 0x6000000ca6b0>, child nodes {
        0:<NSTreeControllerTreeNode: 0x6000000caf70>, child nodes {}
        1:<NSTreeControllerTreeNode: 0x6000000cafe0>, child nodes {}
        2:<NSTreeControllerTreeNode: 0x6000000cb050>, child nodes {}
    }
    1:<NSTreeControllerTreeNode: 0x6080000d1790>, child nodes {
        0:<NSTreeControllerTreeNode: 0x6000000cce80>, child nodes {}
    }
}

And the selectedIndex is 4. 并且selectedIndex为4。

I can't see how to get back to what, in my data model, would be deviceStore[0].serviceStore[2] from this information. 我看不到如何从该信息返回到我的数据模型中的deviceStore [0] .serviceStore [2]。

If I could retrieve the value in the Service ID column from the selected Row, I could simply walk the deviceStore tree to find it. 如果我可以从选定的行中检索“服务ID”列中的值,则只需走到deviceStore树中即可找到它。

I'm sure there's a simply, elegant, easy way to do this that I just haven't found yet, but being new to NSTreeController s and NSOutlineView s I'm lost. 我敢肯定,有一种简单,优雅,简单的方法可以做到这一点,但我还没发现,但是对NSTreeControllerNSOutlineView还是NSOutlineView的。

You may try to access directly the associated object(s) like this: 您可以尝试直接访问关联的对象,如下所示:

let selectedService = treeController.selectedObjects.first as? Service

The docs are here . 文档在这里

also make sure your NSTreeController is correctly configured to use your class' objects: 还要确保将NSTreeController正确配置为使用类的对象:

在此处输入图片说明

Alternatively (if you want to work directly with your data source) you may want to get the index path of the selected object in the NSTreeController : 或者(如果您想直接使用数据源),则可能需要获取 NSTreeController所选对象的索引路径

var selectionIndexPath: IndexPath? { get }

I use following with Core data, 我在核心数据中使用以下代码,

func outlineViewSelectionDidChange(_ notification: Notification) {
    let item = outlineView.item(atRow: outlineView.selectedRow) as! NSTreeNode
    let fileItem = item.representedObject as! FileItemMO

    // Do what you need to do with object fileItem

}

I was never able to actually get back to the TreeController backing-store data baed on where the user clicks in the TreeView. 我从来没有真正回到过以用户在TreeView中单击的位置为基础的TreeController后备存储数据。 What I was able to do was to work backwards to the data though. 能够做的是,虽然向后工作数据。

func outlineViewSelectionDidChange(_ notification: Notification) {
    let selectedIndex = (notification.object as AnyObject).selectedRow!
    let selCol1 = outlineView.view(atColumn: 0, row: selectedIndex, makeIfNecessary: false)?.subviews.last as! NSTextField
    let selCol2 = outlineView.view(atColumn: 1, row: selectedIndex, makeIfNecessary: false)?.subviews.last as! NSTextField

    let devName = selCol1.stringValue
    let devID = selCol2.stringValue
...
}

I could then 'walk' the deviceStrore array until I found the devName and devID in it, and deal with it accordingly. 然后,我可以“遍历” deviceStrore数组,直到在其中找到devNamedevID并进行相应处理。

Probably not the most elegant solution, but at least it finally works. 可能不是最优雅的解决方案,但至少最终可以奏效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM