【问题标题】:TornadoFX - how to fix ListView with a custom cell factory not updating properly when items are deleted?TornadoFX - 如何使用自定义单元工厂修复 ListView 在删除项目时无法正确更新?
【发布时间】:2018-08-20 00:19:18
【问题描述】:

我有一个 ListView 显示来自我的域模型的自定义对象,如果我使用自定义单元工厂在列表的每一行中显示对象的属性,我在删除项目时会出现奇怪的行为。如果该项目不是列表中的最后一项,则已删除的项目仍然可见,而最后一项则消失。但是,该项目已按预期从支持列表中删除,尝试删除幻像对象没有进一步的效果。

显示似乎没有正确刷新,因为在任意调整窗口大小后,列表最终会刷新到其预期值。我尝试手动在ListView 上调用refresh(),但效果不明显。

删除我的自定义单元工厂解决了这个问题,我看到其他使用标准 JavaFX (ListView using custom cell factory doesn't update after items deleted) 遇到类似问题的帖子通过更改 updateItem(Object item, boolean empty) 的实现来解决问题,但我可以不知道如何在 TornadoFX 中做到这一点。

这是一个演示更新问题的示例(但不是幻像项,仅当删除按钮是自定义单元格的一部分时才会发生):

package example

import javafx.scene.control.ListView
import tornadofx.*

data class DomainClass(val name: String, val flag1: Boolean, val flag2: Boolean, val info: String)

class UpdateIssue : App(UpdateIssueView::class)

class UpdateIssueView : View() {

    val listSource = mutableListOf(
            DomainClass("object1", true, false, "more info"),
            DomainClass("object2", false, true, "even more info"),
            DomainClass("object3", false, false, "all the info")
    ).observable()
    var lst: ListView<DomainClass> by singleAssign()

    override val root = vbox {
        lst = listview(listSource) {
            cellFormat {
                graphic = cache {
                    hbox {
                        textfield(it.name)
                        combobox<Boolean> {
                            selectionModel.select(it.flag1)
                        }
                        combobox<Boolean> {
                            selectionModel.select(it.flag2)
                        }
                        textfield(it.info)
                    }
                }
            }
        }
        button("delete") {
            action {
                listSource.remove(lst.selectedItem)
            }
        }
    }
}

非常感谢任何帮助!

【问题讨论】:

  • 跳过缓存或使用正确绑定实现单元格片段以避免重新创建 UI 元素:)
  • @EdvinSyse 感谢您的指点。顺便说一句,喜欢这个框架。
  • 谢谢 :) 对于简短的评论,如果是完整的答案,请在度假时使用最少的 Internet 访问 :) 最可扩展和性能最好的解决方案将是一个片段。

标签: tornadofx


【解决方案1】:

@Edvin Syse 提出的删除缓存块的建议为我解决了这个问题(尽管请注意,他还说更高效的解决方法是实现 ListCellFragment,我在这里没有这样做):

    ....
    lst = listview(listSource) {
        cellFormat {
            graphic = hbox {
                textfield(it.name)
                combobox<Boolean> {
                    selectionModel.select(it.flag1)
                }
                combobox<Boolean> {
                    selectionModel.select(it.flag2)
                }
                textfield(it.info)
            }
        }
    }

【讨论】:

    【解决方案2】:

    我注意到 ComboBoxes 除了 it.flag1 和 flag2 之外没有显示任何其他可选值。您需要将 values 属性设置为 true/false 或 true/false/null。然后可以直接设置值项。

    lst = listview(listSource) {
        cellFormat {
            graphic = hbox {
                textfield(it.name)
                combobox(values=listOf(true, false)) {
                    value = it.flag1
                }
                combobox(values=listOf(true, false)) {
                    value = it.flag2
                }
                textfield(it.info)
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 2014-07-23
      • 1970-01-01
      • 2023-04-11
      相关资源
      最近更新 更多