Как программно развернуть combobox? | |
---|---|
At Сообщений: 187 Дата регистрации: 29.08.2006 |
Есть combobox на форме
Стиль dropdown list rowsourcetype = 6 rowsource = 'table.field1' controlsource = 'table.field1' Нужно чтобы по нажатию энтера при фокусе на комбобоксе, комбобокс раскрывался. Пробовал в keypress LPARAMETERS nKeyCode, nShiftAltCtrl DO CASE case nKeyCode = 13 thisform.combo1.DropDown nodefault endcase не помогает. |
Re: Как программно развернуть combobox? | |
---|---|
At Сообщений: 187 Дата регистрации: 29.08.2006 |
Извиняюсь, поиском не нашел, а в Faq не посмотрел, а оно там есть(
Lparameters nKeyCode, nShiftAltCtrl DO CASE case nKeyCode = 13 KEYBOARD '{ALT+DNARROW}' PLAIN CLEAR nodefault endcase Исправлено 3 раз(а). Последнее : At, 14.03.11 13:10 |
Re: Как программно развернуть combobox? | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Есть абсолютно бессмысленная и даже вредная вешь. Выбор из списка запоминается в тот же самый список Надеюсь в реальном комбобоксе это всё же разные таблицы ------------------ WBR, Igor |
Re: Как программно развернуть combobox? | |
---|---|
pioner-v Сообщений: 1656 Дата регистрации: 01.05.2010 |
Попробуйте так(поместите этот код в метод KeyPress комбобокса):
|
Re: Как программно развернуть combobox? | |
---|---|
At Сообщений: 187 Дата регистрации: 29.08.2006 |
Очень даже не бессмысленная. Например мне нужно программно установить в комбобоке нужный выбор. Если не использовать контрол соурс придется мудрить с индексом элемента в списке. С такими настройками как у меня достаточно встать на табличку и выполнить locate for. Да и по дефолту отображается первое значение в таблице, а не пустое поле как в случае без указания контролсоурса. |
Re: Как программно развернуть combobox? | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Если не бессмысленная, значит вредная. Установить в комбобоксе "нужное значение" можно не только по индексу, но и просто .Value="что надо"
То что у тебя написано, вызывает при каждом изменении комбо ЗАПИСЬ выбранного значения обратно в таблицу (особенно это "приятно" если курсор источник открыт в ReadOnly). ControlSource это двусторонняя связь - не только "считать из источника", но и "записать выбор обратно". При этом комбо привязанный к курсору (с источником Fields) и так вызывает перемещение указателя записи в оном при выборе - независимо от того прописано что в ControlSource или нет. Обратно, конечно же, не будет работать - но это запросто реализовать например через This.Value = table.field1 в рефреше комбо - т.к. и в твоём случае без рефреша контрола (а скорее даже всей формы) после перемещения указателя оно работать не будет - тупо будет обратно перебрасывать на "старое значение"... ------------------ WBR, Igor |
Re: Как программно развернуть combobox? | |
---|---|
At Сообщений: 187 Дата регистрации: 29.08.2006 |
1)по индексу значительно удобнее - не нужно думать о типах значения, тримах и прочей фигне. 2)Ну вот свеже сделанная тестовая форма. Курсор в ридонли, все прекрасно работает как при програмных так и при ручных шевелениях курсора. Пробовал привязать к нормальной таблице - изменений в таблице при style = dropdownlist никаких. 3)рефреша комбобокса хватает |
Re: Как программно развернуть combobox? | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Сам себе противоречишь - то "неудобно" по индексу, то удобно...
Касательно "примера" - ну если не смотреть на то что при "выборе" значения появляется в статусбаре надпись о том что "The record is read-only", и что сам выбор подтормаживает где-то на секунду... Для не RO курсора - можете мне поверить, запись ПРОИСХОДИТ. Просто он меняет значение на "само же себя", поэтому в большинстве случаев изменений "не видно". Чётко видно что меняется дата изменения файла, если есть триггер на обновление - он тоже срабатывает. Про рефреш - я и писал что БЕЗ рефреша не работает, а С ним - гораздо лучше работает строчка This.Value = table.field1 в обработчике события Refresh. И главное - нет никаких мозгодробящих логических циклов - пишу в поле значение из этого же поля. Впрочем каждый ССЗБ - нравится "индусский стиль" в программировании - пиши так, только не удивляйся если другие будут плеваться смотря твой код ------------------ WBR, Igor |
Re: Как программно развернуть combobox? | |
---|---|
Владимир Максимов Автор Сообщений: 14100 Откуда: Москва Дата регистрации: 02.09.2000 |
Угу. А теперь укажите в качестве ControlSource поле, отличное от символьного или числового. Например, Date или Logical. Немедленно получите сообщение об ошибке о несовпадении типов. Т.е. именно в Вашем случае приходится таки очень даже думать "о типах значения, тримах и прочей фигне"
Ошибок действительно нет. Но выполняется блокировка текущей (выбранной) записи. Некая не явная попытка обновления. Попробуйте такой "фокус". Откройте Вашу таблицу-источник в другом сеансе FoxPro (можно в Private DataSession) и заблокируйте ее через FLOCK(). А потом вернитесь к своему ComboBox и попробуйте что-нибудь выбрать. Можно через RLOCK() заблокировать какую-то одну запись, а потом в Combo попытаться ее выбрать. Результат будет тот же |
Re: Как программно развернуть combobox? | |
---|---|
At Сообщений: 187 Дата регистрации: 29.08.2006 |
[quote Igor Korolyov]1)Сам себе противоречишь - то "неудобно" по индексу, то удобно...
2)Касательно "примера" - ну если не смотреть на то что при "выборе" значения появляется в статусбаре надпись о том что "The record is read-only", и что сам выбор подтормаживает где-то на секунду... 3)Про рефреш - я и писал что БЕЗ рефреша не работает, а С ним - гораздо лучше работает строчка This.Value = table.field1 в обработчике события Refresh. И главное - нет никаких мозгодробящих логических циклов - пишу в поле значение из этого же поля. [/quote] 1)по индексному полю таблицы удобно, по индексу комбобокса неудобно 2)никаких надписей не появляется и тормозов тоже 3)Добавил в рефреш This.Value = table.field1, никаких изменений в коде не понадобилось. Ровно те же: select table1 locate for условие combobox.refresh [quote Владимир Максимов] Угу. А теперь укажите в качестве ControlSource поле, отличное от символьного или числового. Например, Date или Logical. Немедленно получите сообщение об ошибке о несовпадении типов. Т.е. именно в Вашем случае приходится таки очень даже думать "о типах значения, тримах и прочей фигне" [/quote] Лично мне не понятно, что не так если в том же хелпе написано: [quote]Если свойство ControlSource установлено в имя поля таблицы или переменную, свойсто Value всегда будет имть тоже самое значение данных и тот же самый тип данных, что и переменная или поле, в которые установлено свойство ControlSource.[/quote] [quote]Once the ControlSource property is set to a field or variable, the Value property always has the same data value and the same data type as the variable or field to which the ControlSource property is set.[/qoute] Именно это мне и нужно - чтобы тип и значение элемента управления было таким же как и в моей таблице. Исправлено 1 раз(а). Последнее : At, 17.03.11 10:50 |
Re: Как программно развернуть combobox? | |
---|---|
Igor VS Сообщений: 2193 Откуда: Харьков Дата регистрации: 26.01.2011 |
Вы у себя в программе устроили, фигурально выражаясь, аттракцион под названием "удав, кусающий себя за хвост". Вам два умных человека говорили, почему этого делать не надо, и какие проблемы можно на этом деле поиметь. Не понимаете сейчас - вам же хуже. Придется срочно понимать в процессе эксплуатации приложения, когда будете горевать над программой, непредсказуемо зависающей в клинче, или думать какого черта указатель уходит с нужной записи без видимых на то причин, или почему при закрытии формы возникает сообщение "update conflict", когда на форме ничего не менялось и т.д. и т.п. Если, конечно, хватит проницательности установить причинно-следственные отношения между проявлением проблемы и ее источником. А отношения эти в вашем случае будут ой какие неочевидные. ------------------ Трехколесный пароход Исправлено 1 раз(а). Последнее : Igor VS, 17.03.11 11:38 |
Re: Как программно развернуть combobox? | |
---|---|
Владимир Максимов Автор Сообщений: 14100 Откуда: Москва Дата регистрации: 02.09.2000 |
Хотите получить проблемы "на ровном месте"? Ну, Вы их получите. Только потом не спрашивайте "почему не работает". Вам уже сказали "почему".
================================================================= ComboBox - это совокупность нескольких объектов: 1. TextBox - он отображает выбранное значение 2. CommandButton - открывает раскрывающийся список 3. ListBox - собственно раскрывающийся список Содержимое ListBox - это специфический массив, содержащий только и исключительно символьные данные. Это значит, что содержимое ListBox не есть то, что указано в свойстве RowSource. Это массив, содержимое которого создано на основе тех данных, которые указаны в свойстве RowSource. Но всегда следует помнить, что это другие данные. При определенном значении свойства RowSourceType (при определенном типе источника данных) FoxPro берет на себя работу по синхронизации перемещения в ListBox и в источнике данных, указанном в RowSource. Но, как правило, подобная синхронизация скорее мешает. Итак, содержимое раскрывающегося списка - это массив символьных (и только символьных) данных. Следовательно, возвращаемое значение - это либо содержимое элемента массива, либо порядковый номер (индекс) строки массива. Естесственно, что содержимое элемента массива имеет символьный тип данных (и только символьный), а порядковый номер - числовой. Как следствие, если ожидаемый тип возвращаемого значения должен быть символьным, то будет возвращено содержимое элемента массива. Если же ожидаемый тип возвращаемого значения должен быть числовым, то будет возвращено значение индекса (номер строки массива). Как определяется ожидаемый тип возвращаемого значения чуть ниже. Это то, как ComboBox будет действовать по умолчанию. Однако у ComboBox есть дополнительная специфическая настройка BoundTo. Если эта настройка имеет значение .T. и ожидаемый тип возвращаемого значения числовой, то в качестве возвращаемого значения будет взято содержимое элемента массива, которое затем будет сконвертировано в числовое значение (вероятно, при помощи функции VAL()). Если ожидаемый тип возвращаемого значения символьный, то настройка BoundTo - не анализируется. Как определяется ожидаемый тип возвращаемого значения? По заданному программистом выбранному значению по умолчанию. Выбранное значение - это свойство Value. Следовательно, если там указать символьное значение, то ComboBox будет возвращать содержимое элемента массива. Если там указать числовое значение, то ComboBox будет возвращать индекс массива или, в случае настройки BoundTo = .T., содержимое элемента массива сконвертированое в число. Однако выбранное значение может быть указано опосредованно, не через свойство Value, а через свойство ControlSource. Свойство ControlSource - это то, где будет храниться (куда будет записываться) выбранное значение. Разумеется, при инициализации объекта из этого же источника будет взято и значение по умолчанию. Как уже было сказано, ComboBox может вернуть либо символьное, либо числовое значение. Как следствие, ControlSource также должен содержать либо символьное, либо числовое значение иначе Вы получите сообщение об ошибке о не соответствии типов. Если Вы не хотите нигде хранить выбранное значение, то для инициализации типа возвращаемого значения следует использовать свойство Value. Как установить значение по умолчанию, при инициализации объекта (при открытии формы)? Прежде всего, следует понимать, что отображаемое значение, не всегда совпадает с выбранным значением. Ну, например, в качестве выбранного значения (свойства Value) может быть указан индекс массива. Тем не менее, на форме в ComboBox Вы видите не индекс, а некий текст. Т.е. отображаемое значение не совпадает с выбранным. Еще раз напомню, что содержимое раскрывающегося списка - это массив. Значит, выбранное значение, это содержиое элемента этого массива. Массив может быть двумерным. Значит, выбранное значение характеризуется двумя координатами: номером строки (индексом) и номером столбца. По умолчанию, выбранное значение - это содержимое первого столбца массива. Но при помощи настройки BoundColumn можно явно указать из какого столбца следует брать значение. Другими словами, столбец массива всегда известен. И надо определить только строку. Строку можно определить явно, просто указав ее номер (свойство ComboBox.ListIndex) или не явно, указав предполагаемое выбранное значение (ComboBox.Value или опосредованно через ComboBox.ControlSource). Во втором случае при инициализации объекта ComboBox попытается найти в раскрывающемся списке указанное значение. Если оно будет найдено, то Вы увидите на форме некое отображаемое значение. Если такого значения нет во внутреннем массиве ComboBox, то и отображаемого значения не будет. Еще один опосредованный вариант определения значения по умолчанию, это случай, когда FoxPro берет на себя работу по синхронизации перемещения по раскрывающемуся списку ComboBox и источнику данных этого самого раскрывающегося списка. В этом случае достаточно будет просто позиционироваться на нужную строку в источнике данных. А уже FoxPro сам синхронизирует положение в раскрывающемся списке и отобразит (если строка массива будет найдена) соответствующее значение. Однако это довольно рискованная стратегия, ведь перемещение по записям таблицы-источника может быть не связано с процессом выбора элемента ComboBox. Тут придется открывать таблицу-источник еще раз в другой рабочей области, чтобы не смешивать поиск в раскрывающемся списке и все прочие операции по работе с данной таблицей. |
Re: Как программно развернуть combobox? | |
---|---|
rhs72 Сообщений: 1934 Откуда: Алматы - Чарджоу Дата регистрации: 21.03.2007 |
Ответ В.Максимова в FAQ !
------------------ "Знание того, что считать ответом, равносильно знанию ответа". |
Re: Как программно развернуть combobox? | |
---|---|
B3ersn3V Сообщений: 595 Откуда: г. Киев Дата регистрации: 22.12.2005 |
+1 ------------------ Не от того, что мы на планете, так солнце светит! |
Re: Как программно развернуть combobox? | |
---|---|
SoccerStudio Сообщений: 5055 Откуда: Подмосковье Дата регистрации: 28.11.2006 |
Ага. А эпиграф к ответу - в качестве заголовка к форуму. |
Re: Как программно развернуть combobox? | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Понятно, т.е. имеется в виду что удобно пользоваться полем id "справочника", отображать при этом его же поле name, но неудобно пользоваться ListIndex комбобокса, т.к. оно (что вполне естественно) в общем случае не будет совпадать с соответствующим id таблицы. Так вот в этом случае стоит использовать 2-х колончатый комбобокс, настроенный примерно вот так RowSourceType=6, RowSource="table1.name, id", BoundColumn=2, BoundTo=.T. ColumnWidth = "200,0" - при этом ControlSource ну никак не должен быть связан с курсором table1 он должен быть связан с другим курсором (с полем куда должен записываться выбор), с глобальной переменной (фи), некоторым пользовательским свойством формы, либо вообще ни с чем не быть связан (ожидаем чисто програмный прямой доступ к "текущему выбору" через Value, или опосредованный - через перемещение указателя записи в table1 - последнее предполагает что table1 не используется более ни в каких комбобоксах/листбоксах или гридах - иначе не уследить за тем кто же из них последний перемещал указатель записи). Появляется - если курсор table1 открыт в режиме NOUPDATE (т.е. он доступен только для чтения) - ещё печальнее если эта же таблица будет открыта в другой сессии (или даже другой программе) и там будет заблокирована некоторая запись этой таблицы (вручную, или автоматически, например при использовании пессимистической буферизации, или при отсутствии всякой буферизации вовсе), или же вся таблица целиком. Это будет банальное зависание при стандартной настройке SET REPROCESS - висим и ждём пока запись/таблицу "отпустят". Именно так - и теперь можно в ControlSource прописать "" - т.е. ОТВЯЗАТЬ комбо! При том оно будет работать ровно так как и предполагается - но уже без указанных неприятных последствий "Не так" сама логика смешивания источника строк комбо и места куда записывается выбор текущего элемента Для этого не обязательно привязывать комбо к полю или даже переменной/свойству (против самой привязки, кстати, никаких возражений - вопрос к тому К ЧЕМУ привязывать! К тому же курсору который есть источник строк - это и есть крайне нехорошо) - достаточно проинициализировать один раз свойство Value. ------------------ WBR, Igor |
© 2000-2024 Fox Club  |