Как заполнить несколько текстовых полей на основе выбранной строки в списке

#c# #winforms #listbox

Вопрос:

Я написал метод, который заполняет несколько строк в списке (но отображает только регистрационный номер). Эти строки называются registrationNumber , hireCost , carMake , carModel , и carYear . Поскольку он отображает только регистрационный номер, я хочу заполнить некоторые текстовые поля, когда я выбираю регистрационный номер в списке.

Я разработал общий метод того, как, по моему мнению, он будет функционировать, но не уверен, как его реализовать.

Код для вставки данных

 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);
}
 

Код для выбора строки

 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";
    } 
}
 

Вот как это может выглядеть, когда я нажимаю на регистрационный номер
, как показано на прилагаемом изображении ниже. Поля справа были заполнены.

Пример

Как я могу ввести значения выбранного регистрационного номера в текстовые поля?

Изменить Вот метод, который получает данные для списка из другой формы:

 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();
}
 

Комментарии:

1. Откуда взялись ваши исходные строки, которые помещены в список? Можно ли его датировать? Вам нужно привязать текстовые поля к столбцам таблицы, чтобы при выборе строки в таблице текстовые поля автоматически заполнялись. См.: social.msdn.microsoft.com/Forums/vstudio/en-US/…

2. Они вводятся из другой формы. Я добавлю код к вопросу

Ответ №1:

В современном программировании существует тенденция отделять ваши данные (= модель) от способа отображения данных (= представление). Если вы разделите их, вы сможете изменить способ отображения данных без необходимости изменять свою модель.

Аналогичным образом вы можете изменить модель, не меняя вид. Например, ваша текущая модель извлекает данные из базы данных, но вам не придется ничего менять в своем представлении, если вы решите прочитать данные из JSON-файла.

Разделение модели и представления также позволяет проводить модульное тестирование модели без форм.

Разделение модели и представления нуждается в чем — то, чтобы склеить их вместе. Этот «адаптер» часто называют моделью представления. Аббревиатура этих элементов часто называется MVVM.

Так что давайте разделимся!

Очевидно, ваша модель имеет представление о машинах, которые можно взять напрокат. Так что нам нужен класс:

 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();
}
 

И Бинго: отображаются все регистрационные номера автомобилей.

Этот дисплей доступен только для чтения. Изменения, которые вносит оператор: Добавление / Удаление строк, изменение регистрационных номеров, не отражаются.

Это может не быть проблемой в вашем текущем приложении, но если позже вы решите показать свои автомобили в представлении DataGrid или захотите использовать этот метод в списке, который оператор может редактировать, вам может потребоваться автоматическое обновление внесенных оператором изменений. В этом случае вам следует использовать список привязок:

 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>();
 

Вернемся к вашему вопросу

Я хочу заполнить некоторые текстовые поля, когда я выбираю регистрационный номер в списке.

Поэтому, если оператор выбирает Регистрационный номер в списке, вы хотите отобразить несколько значений свойств автомобиля выбранного автомобиля.

С помощью конструктора 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();
    ...
}
 

Вывод

Отделяя ваши данные от способа их просмотра, ваш код становится намного проще для чтения. Методы обычно представляют собой одну или две строки кода. Методы очень часто используются повторно, и как модель, так и представление легко изменить. Можно провести модульное тестирование модели без представления.