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)
}
}
}
}
由于我没有看到像列表视图那样的预制类,或许我需要创建类似于它的东西......或者可能有更轻量级的方法?
答案 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
}