2017-07-24 5 views
0

Folowing Beispiel vor:TornadoFX wie Validierung hinzufügen, während der Bearbeitung Tableview

class Item(name: String, number: Int) { 
    val nameProperty = SimpleStringProperty(name) 
    var name by nameProperty 

    val numberProperty by lazy { SimpleIntegerProperty(number) } 
    var number by numberProperty 
} 

class MainView : View("Example") { 
    val items = listOf(Item("One", 1), Item("Two", 2)).observable() 

    override val root = vbox { 
     tableview(items) { 
      column("Name", Item::nameProperty).makeEditable() 
      column("Number", Item::numberProperty).makeEditable(NumberStringConverter()) 
      enableCellEditing() 
     } 
    } 
} 

Wie kann ich eine validator hinzufügen, während Zellen zu bearbeiten? Ist der einzige Weg, dies zu tun, rowExpander mit einigen textfield hinzuzufügen und versuchen, ein Modell dort zu validieren?

Antwort

0

Sie können entweder Ihre eigene cellfactory implementieren und eine Zelle zurückgeben, die im Bearbeitungsmodus ein an ein ViewModel gebundenes Textfeld anzeigt, und eine Beschriftung, falls dies nicht der Fall ist. Alternativ, wenn Sie mit immer die Anzeige einer Textfeld fein sind, können Sie cellFormat und binden das aktuelle Element zu einem ItemModel verwenden können, so dass Sie die Validierung anhängen können:

class ItemModel(item: Item) : ItemViewModel<Item>(item) { 
    val name = bind(Item::nameProperty) 
    val number = bind(Item::numberProperty) 
} 


class MainView : View("Example") { 
    val items = listOf(Item("One", 1), Item("Two", 2)).observable() 

    override val root = vbox { 
     tableview(items) { 
      column("Name", Item::nameProperty).makeEditable() 
      column("Number", Item::numberProperty).cellFormat { 
       val model = ItemModel(rowItem) 
       graphic = textfield(model.number, NumberStringConverter()) { 
        validator { 
         if (model.number.value == 123) error("Invalid number") else null 
        } 
       } 
      } 
     } 
    } 
} 

Es wird wie folgt aussehen:

CellFormat Solution

Während es funktioniert, ist es eine Art verschwenderisch, da die Knoten häufig neu erstellt werden. Ich würde Ansatz Nummer eins empfehlen, wenn Leistung ein Anliegen ist, bis wir cellFragment Unterstützung für TableView wie wir für ListView haben.

EDIT: Ich implementierte cellFragment Unterstützung, so ist es möglich, eine robustere Lösung zu schaffen, die ein Etikett, wenn sie nicht in den Bearbeitungsmodus und eine Validierung von Textfeld zeigen wird, wenn Sie den Bearbeitungsmodus aufzurufen.

class ItemModel : ItemViewModel<Item>() { 
    val name = bind(Item::nameProperty) 
    val number = bind(Item::numberProperty) 
} 


class MainView : View("Example") { 
    val items = listOf(Item("One", 1), Item("Two", 2)).observable() 

    override val root = vbox { 
     tableview(items) { 
      column("Name", Item::nameProperty).makeEditable() 
      column("Number", Item::numberProperty).cellFragment(NumberEditor::class) 
     } 
    } 
} 

class NumberEditor : TableCellFragment<Item, Number>() { 
    // Bind our ItemModel to the rowItemProperty, which points to the current Item 
    val model = ItemModel().bindToRowItem(this) 

    override val root = stackpane { 
     textfield(model.number, NumberStringConverter()) { 
      removeWhen(editingProperty.not()) 
      validator { 
       if (model.number.value == 123L) error("Invalid number") else null 
      } 
      // Call cell.commitEdit() only if validation passes 
      action { 
       if (model.commit()) { 
        cell?.commitEdit(model.number.value) 
       } 
      } 
     } 
     // Label is visible when not in edit mode, and always shows committed value (itemProperty) 
     label(itemProperty) { 
      removeWhen(editingProperty) 
     } 
    } 

    // Make sure we rollback our model to avoid showing the last failed edit 
    override fun startEdit() { 
     model.rollback() 
    } 

} 

Dies ist ab TornadoFX 1.7.9 möglich.

+0

Ich aktualisierte die Antwort mit einer robusteren Lösung mit einem TableCellFragment, das in TornadoFX 1.7.9 eingeführt wird :) –

+0

wow, danke Edvin, sieht für meinen Fall perfekt aus – sk1ey

+0

Großartig! Sie können es auschecken, indem Sie bereits einen Snapshot Build verwenden :) –

Verwandte Themen