我无法将fxml集合绑定到自定义模板。这里的代码我将如何在xaml中执行:
<ListView ItemsSource="{Binding PersonCollection}">
<StackPanel Orientation="Horizontal">
<Label Content="{Binding FirstName}"></Label>
<ListView ItemsSource="{Binding MiddleNames}">
<Label Content="{Binding}"></Label>
</ListView>
<Label Content="{Binding LastName}"></Label>
</StackPanel>
</ListView>
这里的模型:
class Person
{
String FirstName, LastName;
String[] MiddleNames;
}
布局看起来与此相似:
John Ivy
Robert Downey Junior
Max more middlenames in fact even thousands are possible lastname
可以将可服务的集合绑定到自定义模板吗? 我尝试了细胞嗅觉,但是不能让我的脑袋缠绕它,因为每个人都只使用细绳。
答案 0 :(得分:6)
我不是100%肯定这是你问题的答案,因为我对xaml完全不熟悉,但希望它是......
示例实施
该示例通过将模型对象(Person)设置为FXML加载器的命名空间来工作,这允许您使用FXML中的绑定表达式绑定到对象的属性。
在示例中,模型中最初有一些名称,您可以使用添加和删除按钮修改模型中的绑定列表,以在列表中添加或删除一些其他固定名称。
所有代码都在名为sample.names的包中。
名-display.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.layout.HBox?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Button?>
<VBox xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.names.NameDisplayController">
<HBox prefHeight="150.0" prefWidth="220.0" spacing="5.0" >
<children>
<Label fx:id="firstNameLabel" text="${person.firstName}" />
<ListView fx:id="middleNameList" prefWidth="100.0" items = "${person.middleNames}" />
<Label fx:id="lastNameLabel" text="${person.lastName}" />
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
</HBox>
<HBox alignment="CENTER" spacing="30.0">
<children>
<Button mnemonicParsing="false" onAction="#addName" text="Add" />
<Button mnemonicParsing="false" onAction="#removeName" text="Remove" />
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
</HBox>
</VBox>
NameDisplayApp.java
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import java.io.IOException;
public class NameDisplayApp extends Application {
@Override
public void start(Stage stage) throws IOException {
Person person = new Person(
"Bruce",
new String[] { "Simon", "Larry" },
"Banner"
);
FXMLLoader loader = new FXMLLoader(
getClass().getResource(
"name-display.fxml"
)
);
loader.getNamespace().put(
"person",
person
);
Pane pane = loader.load();
NameDisplayController controller = loader.getController();
controller.setPerson(person);
stage.setScene(new Scene(pane));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
NameDisplayController.java
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
public class NameDisplayController {
private Person person;
private ObservableList<String> sampleNames = FXCollections.observableArrayList(
"George", "Henry", "Wallace"
);
public void setPerson(Person person) {
this.person = person;
}
public void addName(ActionEvent actionEvent) {
if (!sampleNames.isEmpty()) {
person.getMiddleNames().add(
sampleNames.remove(0)
);
}
}
public void removeName(ActionEvent actionEvent) {
if (!person.getMiddleNames().isEmpty()) {
sampleNames.add(
person.getMiddleNames().remove(0)
);
}
}
}
Person.java
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
public class Person {
public StringProperty firstName;
public StringProperty lastName;
private ObservableList<String> middleNames;
public Person(String firstName, String[] middleNames, String lastName) {
this.firstName = new SimpleStringProperty(firstName);
this.middleNames = FXCollections.observableArrayList(middleNames);
this.lastName = new SimpleStringProperty(lastName);
}
public String getFirstName() {
return firstName.get();
}
public StringProperty firstNameProperty() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public ObservableList<String> getMiddleNames() {
return middleNames;
}
public String getLastName() {
return lastName.get();
}
public StringProperty lastNameProperty() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName.set(lastName);
}
}
替代实施
可能有其他(可能更优选的方式)这样做 - 例如通过关联代码中的项目绑定而不是FXML(这是我通常做的)或使用依赖注入系统注入模型。有关注入方法的示例,请参阅afterburner.fx - 虽然我不知道Afterburner是否也将模型对象放入FXML命名空间或仅注入控制器(如果它没有注入FXML命名空间,可能是你可以要求的一个很酷的补充。)