Подтвердить что ты не робот

Combobox не позволяет вводить пользовательский текст, если используется DataBinding


У меня есть следующий класс:

class Address
{
     public string City {get; set;}
     public string Street {get; set;}
}

и у меня есть форма с двумя комбобоксами на ней. Я привязываю эти comboboxes к классу Address:

CityComboBox.DataSource = GetCityDataSource();
StreetComboBox.DataSource = GetStreetDataSource();
Address address = new Address();
CityComboBox.DataBindings.Add("SelectedItem", address, "City");
StreetComboBox.DataBindings.Add("SelectedItem", address, "Street");

База данных городов и улиц не является полной, поэтому иногда пользователь должен писать пользовательские значения в combobox. Проблема в том, что привязка данных combobox не позволяет писать пользовательские значения в это поле. Есть ли обходной путь для такого поведения?
Спасибо заранее!

4b9b3361

Ответ 1

Это работает: (в вашем случае)

Установите DrowdownStyle в Dropdown и привяжите к свойству ComboBox Text вместо SelectedItem.

Для двух комбинированных ящиков вам нужно привязать текст к свойствам City и Street экземпляра класса Address. Кажется, вы не хотите добавлять какие-либо элементы в List<string>, возвращаемые методами GetCityDataSource() или GetStreetDataSource().

Следовательно, поскольку свойство Text target для привязки ниже не перепутано с (неизменяемым), коллекция элементов, связанная с вашим источником данных, следующие изменения должны сделать ваш код работать: (Я проверил сущность изменений кода ниже, используя VS 2010).

 CityComboBox.DataSource = GetCityDataSource(); 
 StreetComboBox.DataSource = GetStreetDataSource(); 
 Address address = new Address(); 
 CityComboBox.DropDownStyle = ComboBoxStyle.DropDown
 CityComboBox.DataBindings.Add("Text", address, "City");
 StreetComboBox.DropDownStyle = ComboBoxStyle.DropDown
 StreetComboBox.DataBindings.Add("Text", address, "Street");

PS! Подход выше работает только тогда, когда вы хотите использовать данные City и Street для простого пользовательского интерфейса. Вы не устанавливаете постоянную связь между адресными данными и объектами, для которых вы регистрируете адрес. Если вы хотите, чтобы ваши данные были нормализованы, вы хотели бы хранить внешние ключи для записей в таблицах City, Street (и, возможно, Zipcode).

С пользовательскими названиями улиц и городов вы получите много нечетких данных (например, Washington DC, WASHINGTON D.C., St. Patricks rd., Saint Patrick road и т.д.), что в будущем затруднит выполнение SQL запросов с использованием WHERE Street = [something]. С нормализованными данными вы просто выполните WHERE StreetID = [specificID].

ИЗМЕНИТЬ

Если вы одновременно пытаетесь сделать две вещи в одном и том же диалоге пользовательского интерфейса (как для выбора улицы, так и для города, например, для профиля человека/компании, а также для обслуживания внутренних списков улиц и городов), тогда вы должны использовать другой подход.

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

Вы также можете добавить фиктивную запись в источник данных combobox со строкой "[добавить новый]" и использовать специальную обработку, когда этот элемент выбран. Поскольку этот подход подразумевает подделку исходного списка для комбо, он может легко стать немного грязным.

Пример приложения

Образец формы с привязкой к базе данных ComboBox, которая использует источник данных List<string>

enter image description here

Ключевые свойства после выбора предопределенной улицы

enter image description here

Ключевые свойства после выбора пользовательской улицы

enter image description here

Ответ 2

Проверьте это:

public partial class Form1 : Form
{
    BindingList<Address> list;
    public Form1()
    {
        InitializeComponent();

        list = new BindingList<Address>();
        //lets add some example data:
        list.Add(new Address{ City = "London", Street = "Street 111" });
        list.Add(new Address { City = "Barcelona", Street = "Street 222" });
        comboBox1.DataSource = list;

        //I am not sure what you want to show (and what to use as a value). You can change this!
        comboBox1.DisplayMember = "Street";
        comboBox1.ValueMember = "City";
    }

    private void button1_Click(object sender, EventArgs e)
    {
        //adding new object to the list:
        string _city = textBox1.Text;
        string _street = textBox2.Text;
        if (_city != String.Empty && _street != String.Empty)
        {
            list.Add(new Address { City = _city, Street = _street });
            textBox1.Text = "";
            textBox2.Text = "";
        }
    }
}

class Address
{
    public string City { get; set; }
    public string Street { get; set; }
}

Ответ 3

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

Ответ 4

Как я это делаю (я не использую привязку данных):

  • Инициализировать экземпляр List<T> (может быть List<Address> в вашем случае).
  • Прочитайте элементы базы данных в List<T>.
  • Заполните поля со списком, используя элементы, найденные в List<T>.
  • Когда создается новый элемент, вставьте этот элемент в свою базу данных.
  • Перезагрузка вверху (поддается процедуре, которую вы можете вызвать в любое время).

Если вам необходимо привязать данные, вы можете скрыть поле со списком и отобразить текстовое поле, пока пользователь не сохранит вашу информацию, но вам все равно нужно будет записать в свою базу данных и снова прочитать данные.

Ответ 5

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

Ответ 6

Проблема - наличие combobox привязка данных не позволяет писать пользовательские значения в это поле. Является существует обходное решение для этого поведения?

Так что не связывай это! Напишите свои собственные методы для заполнения combobox и обработчика событий для редактирования элементов.