2014-01-17 2 views
0

Я прочитал всевозможные документы по всему миру о том, что должно быть крайне распространенной и безболезненной реализацией. Поскольку я не нашел последовательного и гладкого ответа (даже сайт Embarcadero описывает некоторые свойства неправильно!) Я собираюсь опубликовать «короткое» руководство.Как быстро заполнить поле со списком данных базы данных (VCL)

Типичный, часто используемый случай использования: разработчик просто хочет безболезненно показать пару данных, извлеченных из базы данных, в поле со списком (т. Е. Выбор языка), получить от пользователя выбор и все.

Требования:

  1. Delphi, более или менее любой версии. VCL покрыт.
  2. Таблица базы данных. Предположим, что простая таблица с полями id и value.
  3. DataSet (включая запросы и ClientDataSets).
  4. Источник данных, связанный с DataSet.
  5. TDBLookupComboBox, связанный с источником данных, который должен отображать список значений и «возвращать» текущий выбранный идентификатор.

ответ

6

Во-первых, мы решаем, является ли порядок сортировки тем, который мы хотим или нет, и если все элементы в этой таблице должны быть показаны. Чаще всего достаточно простого предложения ORDER BY или индекса DataSet. Если это не так, мы можем добавить поле sort_order и заполнить его целыми числами, представляющими наш заказный порядок сортировки. Если мы хотим показать только некоторые элементы, мы добавим поле visible или enabled и используем его в нашем SQL. Пример:

SELECT id, value 
FROM my_database_table 
WHERE visible = 1 
ORDER BY sort_order 

Я определил visible как INTEGER и проверки его против 1 и не TRUE, потому что многие базы данных (в том числе наиболее часто используемых SQLite) имеют слабую поддержку булевы.

Затем необязательная, но удивительно часто хорошая идея: временно добавьте TDBGrid в форму, привяжите ее к тому же TDataSource TLookupComboBox и убедитесь, что вы действительно видите, что нужные данные заполняют его. На самом деле легко опечатать что-то в запросе (при условии, что вы используете SQL DataSet) и не получаете никаких данных, и тогда вам остается недоумевать, почему TDBLookupComboBox не будет заполняться. Как только данные правильно отображаются, удалите сетку ,

Еще одна разумная идея - использовать ClientDataSets для таких реализаций: из-за того, как они работают, они будут «кэшировать» несколько строк, содержащихся в вашем поиске, при запуске программы, а затем больше не будут доступа к базе данных (и замедления и трафика) потребуется.

Теперь откройте свойства TDBLookupCombobox и заполнить только следующие из них:

ListSourceнеDataSource): установите его на TDataSource, подключенный к DataSet вы хотите, чтобы показать значение.
ListField: укажите имя поля, которое вы хотите видеть. В нашем демонстрационном случае это будет поле value.
KeyField: установите имя поля, значение которого вы хотите, чтобы программа вернула вас. В нашей демонстрации это будет поле id.

Не забудьте проверить свойство TabOrder, есть еще люди, которые любят навигации по элементам управления, нажав клавишу TAB и ничто не раздражает больше, чем видеть выбор прыжкового вокруг случайно, как ваш ComboBox был помещен последним на несмотря на графическое отображение второго!

Если вам нужно показать форму и прочитать выбранное значение TDBLookupComboBox, когда пользователь нажмет кнопку, вы в значительной степени отсортированы.
Все, что вам нужно сделать в обработчике события OnClick для кнопки будет считывать значение поля со списком с этим кодом:

SelectedId := MyCombo.KeyValue; 

Где SelectedId любая переменная, где для хранения возвращаемого значения и MyCombo, конечно, имя вашего TDBLookupComboBox. Обратите внимание, что KeyValue не будет содержать текст, который пользователь видит на экране, но значение поля id, указанное в KeyField. Таким образом, если наш пользователь выбрал строку к базе данных:

id= 5 
value= 'MyText' 

MyCombo.KeyValue должен содержать 5.

Но что, если вам нужно динамически обновлять материал на форме, в зависимости от выбора пользователя со списком? Для нашего TDBLookupComboBox нет события OnChange! Поэтому, если вам нужно динамически обновлять материал в соответствии с выборами со списком, вы, по-видимому, не сможете. Вы можете попробовать различные события «OnExit» и т. Д., Но все они имеют серьезные недостатки или побочные эффекты.
Одним из возможных решений является создание нового компонента, наследующего от TDBLookookComboBox, единственной задачей которого является публикация скрытого события OnChange. Но это слишком много, не так ли?

Есть еще один способ: перейти к DataSet Ваш TDBLookupComboBox привязан к (через DataSource). Откройте его события и дважды щелкните по его событию OnAfterScroll. Там вы можете хорошо имитировать событие OnChange. Для демонстрации добавьте одну целую переменную и поле TEdit к форме и назовите их: SelectedId и EditValue.

procedure TMyForm.MyDataSetAfterScroll(DataSet: TDataSet); 
var 
    SelectedId : integer; 

begin 
    SelectedId := MyDataSet.FieldByName('id').AsInteger; 
    EditValue.Text := MyDataSet.FieldByName('value').AsString; 
end; 

Вот так: вы можете заменить эти две демо-линии с вашими собственными вызовами процедуры и все, что вам может понадобиться, чтобы динамически обновлять формы базирование на выбор пользователя в вашем поле со списком.

Небольшое предупреждение: использование DataSet OnAfterScroll имеет также один недостаток: событие вызывается чаще, чем вы думаете. Например, он может вызываться, когда набор данных открывается, но также вызывается более одного раза во время навигации по файлам. Поэтому ваш код должен иметь дело с вызовом чаще, чем необходимо.

На этом этапе вы можете потирать руки и думать, что ваша работа завершена!

Совсем нет! Просто создайте небольшое демонстрационное приложение, реализующее все вышеперечисленное, и вы заметите, что ему не хватает важного штриха: когда он начинается, поле со списком имеет досадный «пустой» выбор по умолчанию. То есть, даже если ваша база данных содержит 4 варианта, форма сначала показывает пустое поле со списком. Как сделать один из ваших вариантов автоматически отображаемым «заранее выбранным» в поле со списком, которое вы и ваши пользователи ожидают?

Простой!

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

MyCombo.KeyValue := DefaultId; 

Например, с помощью базы данных выборки строки размещены выше, вы бы написать:

MyCombo.KeyValue := 5; 

и поле со списком отобразит: «MyText» в качестве предварительно выбранного варианта, когда пользователь открывает форму.

Конечно, вы можете предпочесть более элегантный и привлекательный способ установить ключ по умолчанию, чем жесткое кодирование его значения по умолчанию. В примере вы можете указать первое алфавитно упорядоченное текстовое описание, содержащееся в вашей таблице базы данных, или любой другой критерий. Но основным механиком является тот, который показан выше: получите значение ключа/идентификатора любым желаемым способом, а затем назначьте его свойству KeyValue.

Благодарим за чтение этого до конца!

+0

Спасибо, ты мне помог – topher

Смежные вопросы