TornadoFX中的flowpane碎片

时间:2018-05-21 06:56:59

标签: tornadofx

TornadoFX文档describe using the ListCellFragment将列表控件中的每个单元格绑定到列表中的每个项目模型...想知道如何在流程窗格中执行类似的操作。我想使用这种类在每个单元格中渲染一组控件和一个SVG绘图。 (因此它将替换下面示例代码中的按钮组件,并以某种方式将shapeItem模型绑定到它)。

class LibraryView : View("Current Library") {
    val shapeLibraryViewModel : LibraryViewModel by inject()
    override val root = anchorpane{
        flowpane {
            bindChildren(shapeLibraryViewModel.libraryItemsProperty){
               shapeItem -> button(shapeItem.nameProperty)
            }
        }
    }
}

由于我没有看到像列表视图那样的预制类,或许我需要创建类似于它的东西......或者可能有更轻量级的方法?

1 个答案:

答案 0 :(得分:0)

使用ItemFragment有点矫枉过正,因为片段的itemProperty永远不会改变(每当libraryItemsProperty更改时,都会为每个项创建一个新片段。但是,如果您的视图逻辑为每个项目都是实质性的,这种方法将提供一种分离和包含该逻辑的简洁方法,因此它可能是值得的。这是一个完整的例子,您可以将其作为起点。

class ShapeItemFragment : ItemFragment<ShapeItem>() {
    val shapeModel = ShapeItemModel().bindTo(this)

    override val root = stackpane {
        label(shapeModel.name)
    }
}

class ShapeItem(name: String) {
    val nameProperty = SimpleStringProperty(name)
}

class ShapeItemModel : ItemViewModel<ShapeItem>() {
    val name = bind(ShapeItem::nameProperty)
}

class LibraryViewModel : ViewModel() {
    val libraryItemsProperty = SimpleListProperty<ShapeItem>(
            listOf(
                    ShapeItem("Shape 1"),
                    ShapeItem("Shape 2")
            ).observable()
    )
}

class LibraryView : View("Current Library") {
    val shapeLibraryViewModel: LibraryViewModel by inject()

    override val root = anchorpane {
        flowpane {
            bindChildren(shapeLibraryViewModel.libraryItemsProperty) { shapeItem ->
                val itemFragment = find<ShapeItemFragment>()
                itemFragment.itemProperty.value = shapeItem
                itemFragment.root
            }
        }
    }
}

略微更轻的版本是手动将参数传递到片段中,只需扩展片段:

class ShapeItemFragment : Fragment() {
    val item: ShapeItem by param()

    override val root = stackpane {
        label(item.nameProperty)
    }
}

您仍然可以绑定ShapeItem内部属性的更改,因为底层项目无论如何都不会更改(如ItemFragment所示)。

您的bindChildren声明将如下所示:

bindChildren(shapeLibraryViewModel.libraryItemsProperty) { shapeItem ->
    find<ShapeItemFragment>(ShapeItemFragment::item to shapeItem).root
}