如何根据列表框中的选定行填充多个文本框

How to fill multiple textboxes based on selected row in listbox

我写了一个方法来填充列表框中的多行(但只显示注册号)。这些行称为 registrationNumberhireCostcarMakecarModelcarYear。因为它只显示注册号,所以当我 select 列表框中的注册号时,我想填充一些文本框。

我已经制定了一个通用方法,我相信它会如何运作,但我不确定如何实施它。

插入数据的代码

public void UpdateListBox(string registrationNumber, string hireCost, string carMake, string carModel, string carYear) { 
foreach (string item in listBoxVehicles.Items)
    {
        if (item.Contains(registrationNumber))
        {
            MessageBox.Show("Registration Number: " + registrationNumber + " already exists in the list! Please try another!");
            return;
        }
    }
    listBoxVehicles.Items.Add(registrationNumber);
}

selecting 行的代码

private void PopulateTextBoxes() {
    if (listBoxVehicles.SelectedIndex != -1)
    {
        textBoxHireCost.Text = "Selected index hireCost";
        textBoxMake.Text = "Selected index carMake";
        textBoxModel.Text = "Selected index carModel";
        textBoxYear.Text = "Selected index carYear";
    } 
}

这是我点击注册号时的样子 如下图所示。右侧的字段已填充。

如何将 selected 注册号的值填充到文本框中?

编辑 这是从另一个表单获取列表框数据的方法:

private void StoreData()
{
    //Store Data
    HomeForm list = (HomeForm)Application.OpenForms["HomeForm"];
    list.UpdateListBox(textBoxRegistrationNumber.Text, textBoxHireCost.Text + "     ", textBoxMake.Text + "     ", textBoxModel.Text + "     ", textBoxYear.Text);
    this.Hide();
}

在现代编程中,倾向于将数据(= 模型)与数据显示方式(= 视图)分开。如果将它们分开,您将能够更改显示数据的方式,而无需更改模型。

同样,您可以更改模型,而无需更改视图。例如,您当前的模型从数据库中获取数据,但如果您决定从 JSON 文件中读取数据,则无需更改视图中的任何内容。

模型和视图的分离还支持在没有表单的情况下对模型进行单元测试。

模型和视图的分离需要一些东西将它们粘合在一起。这个“适配器”通常称为视图模型。这些项目的缩写通常称为 MVVM。

所以我们分开吧!

显然您的模型具有可以租用汽车的概念。所以我们需要一个 class:

class Car
{
    public string RegistrationNumber {get; set;}
    public decimal HireCost {get; set;}
    public int ManufacturingYear {get; set;}
    ... // etc.
}

当然,我们需要一个程序来获取必须显示的汽车:

public IEnumerable<Car> FetchCars(...)
{
    // TODO implement; out of scope of the question
}

您使用可视化设计器添加了列表框。此列表框应显示汽车,并且对于每辆汽车,它应仅显示注册号。

您可以使用 visual studio 设计器执行此操作,另一种方法是在构造函数中执行此操作:

public MyForm()
{
    InitializeComponent();

    // From ever Car in the ListBox display the value of property RegistrationNumber
    listBox1.Displayember = nameof(Car.RegistrationNumber);
}

显示汽车:

private ICollection<Car> DisplayedCars
{
    get => (ICollection<Car>)this.listBox1.DataSource;
    set => this.listBox1.DataSource = value;
}

public void DisplayCars()
{
    var carsToDisplay = this.FetchCars();
    this.DisplayedCars = carsToDisplay.ToList();
}

还有宾果游戏:显示所有汽车的注册号。

此显示是只读的。操作员所做的更改:添加/删除行、更改注册号不会反映出来。

这在您当前的应用程序中可能不是问题,但如果稍后您决定在 DataGridView 中显示您的汽车,或者如果您想在操作员可以编辑的 ListBox 中使用此方法,您可能需要自动更新操作员所做的更改。在这种情况下,您应该使用 BindingList:

private BindingList<Car> DisplayedCars
{
    get => (BindingList<Car>)this.listBox1.DataSource;
    set => this.listBox1.DataSource = value;
}

获取所选汽车:

private Car SelectedCar => (Car)this.listBox1.SelectedItem;

或者如果您允许多选:

private IEnumerable<Car> SelectedCars = this.listBox1.SelectedItems.Cast<Car>();

回到你的问题

I want to populate some textboxes when I select the registration number in the listbox.

因此,如果操作员在列表框中选择了一个注册号,则需要显示所选汽车的汽车属性的多个值。

使用visual Studio设计器,或在构造函数中:

this.listBox1.SelectedIndexChanged += OnCarSelected;

private void OnCarselected(object sender, ...)
{
    Car selectedCar = this.SelectedCar;
    this.DisplayCarProperties(selectedCar);
}

private void DisplayCarProperties(Car car)
{
    this.textBoxHireCost.Text = car.HireCost.ToString(...);
    this.textBoxYear.Text = car.ManufacturingYear.ToString();
    ...
}

结论

通过将数据与查看数据的方式分开,您的代码更易于阅读。这些方法通常是一两行代码。方法是高度可重用的,模型和视图都很容易改变。可以在没有视图的情况下对模型进行单元测试。