【问题标题】:fragment for flowpane in TornadoFXTornadoFX 中流窗格的片段
【发布时间】:2018-05-21 06:56:59
【问题描述】:

TornadoFX 文档describe using the ListCellFragment 将列表控件中的每个单元格绑定到列表中的每个项目模型。我想知道如何在flowpane 中做类似的事情。我想使用这种类在每个单元格中呈现一堆控件和一个 SVG 绘图。 (因此它将替换下面示例代码中的button 组件,并以某种方式将shapeItem 模型绑定到它)。

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

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

【问题讨论】:

    标签: tornadofx


    【解决方案1】:

    使用 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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多