#c# #.net #wpf #vb.net #xaml
Вопрос:
Я хочу заполнить поле со списком при срабатывании события GotFocus. Я попытался заполнить свой список в событии GotFocus, но, похоже, это не работает. Элементы видны в выпадающем меню, но когда я хочу выбрать один из них, коллекция очищается
Нажмите на выпадающий список :
Попробуйте выбрать первый пункт :
Вот мой код :
Private Sub agence_GotFocus(sender As Object, e As RoutedEventArgs) Handles agence.GotFocus
strsql = "Select age_cpt, age_abrege ' ' age_nom as age_abregenom from gen_agence where age_soc = " amp; societe.SelectedValue
Dim da As New SqlDataAdapter(strsql, connSQLServer)
Dim ds As New DataSet()
da.Fill(ds, "t")
agence.ItemsSource = ds.Tables("t").DefaultView
agence.DisplayMemberPath = "age_abregenom"
agence.SelectedValuePath = "age_cpt"
End Sub
Как я могу это сделать ?
Я не хочу использовать MVVM.
Комментарии:
1. «Я не хочу использовать MVVM». — почему? MVVM-это типичная реализация WPF. Многое гораздо сложнее реализовать вне этого шаблона.
2. Покажите код вашей текущей реализации (XAML и Sharp), соответствующий вашей проблеме.
3. @EldHasp я знаю, но мне нужно перенести приложение VBA в WPF VB.Net. Поэтому я хочу сохранить существующий код как можно больше.
4. @EldHasp Я обновил свой вопрос и добавил немного кода
5. Я не могу воспроизвести вашу проблему. Выполнено простейшее назначение источнику массива строк
comboBox.ItemsSource ="First Second Third".Split();
. Установите точку останова после назначения таблицы (в строкеagence.DisplayMemberPath = ...
) и проверьте содержимое этой таблицы. Может быть, он у вас пустой?
Ответ №1:
Проблема в том, что это событие срабатывает несколько раз.
Ниже я покажу демо-код в Sharpe (у меня нет VB.Сеть загружена в студию), но код прост, вы должны повторить его самостоятельно на BASIC без каких-либо проблем.
private void OnGotFocus(object sender, RoutedEventArgs e)
{
Debug.WriteLine( eventCount);
ComboBox comboBox = (ComboBox)sender;
// Try the second option by excluding the following line
if (comboBox.ItemsSource == null)
comboBox.ItemsSource = "First,Second,Third".Split(',');
}
Код должен проверять наличие null, чтобы не повторно подключать коллекцию.
Комментируя эту строку, вы воспроизведете свою проблему.
После запуска на выполнение и попытки выбрать элемент, вы увидите в окне «Вывод», что событие произошло несколько раз.
Похоже, что изменение списка в момент его расширения каким-то образом нарушает логику внутренних привязок выпадающего списка.
Есть несколько способов исправить это, но для этого нам нужно знать, почему вы выбрали эту инициализацию элемента — когда на нем сосредоточено внимание.
Несколько способов:
- Обнуление источника перед назначением новой коллекции.
private void OnGotFocus(object sender, RoutedEventArgs e)
{
Debug.WriteLine( eventCount);
ComboBox comboBox = (ComboBox)sender;
comboBox.ItemsSource = null;
comboBox.ItemsSource = "First,Second,Third".Split(',');
}
- Установка коллекции один раз при загрузке выпадающего списка.
<ComboBox Loaded="OnLoaded"/>
private void OnLoaded(object sender, RoutedEventArgs e)
{
Debug.WriteLine( eventCount);
ComboBox comboBox = (ComboBox)sender;
comboBox.ItemsSource = "First,Second,Third".Split(',');
}
Возможны и другие варианты реализации, но мне нужно знать больше деталей о вашей задаче, чтобы выбрать, как лучше всего ее выполнить.
Ответ на дополнительный вопрос:
Обнуление источника перед назначением новой коллекции-хорошая идея. Теперь я могу навести курсор мыши на значения в выпадающем меню. Однако, когда я выбираю значение, поле очищается.
Если это не строковый массив, то выделение можно очистить. Когда вы входите в событие, вы каждый раз заново создаете таблицы. И строки этих таблиц, хотя они одинаковы по содержанию, не будут считаться одним и тем же экземпляром. Вы выбрали строку из одной таблицы, затем переписали источник, и в новом источнике этой строки нет. Выбор будет сброшен.
Я уже писал выше, что для того, чтобы выбрать оптимальное решение, мне нужна более подробная информация о вашей проблеме.
Способ, который вы выбрали для инициализации списка, очень необычен. Каждый раз, когда вы работаете в выпадающем списке, вы делаете запросы к базе данных три — четыре раза. Я никогда не встречал такой реализации и не понимаю ее смысла.
Объясните, зачем вам это нужно?
Комментарии:
1. Обнуление источника перед назначением новой коллекции-хорошая идея. Теперь я могу навести курсор мыши на значения в выпадающем меню. Однако, когда я выбираю значение, поле очищается.
Ответ №2:
Я нашел способ сделать то, что хотел : использовать DropDownOpened
событие вместо GotFocus
Private Sub agence_DropDownOpened(sender As Object, e As EventArgs) Handles agence.DropDownOpened
'... Fill the ComboBox
End Sub
Заполните a ComboBox
в GotFocus
событии работает в VBA, но не в VB.Net.
В VB.Сеть, которую я не могу использовать GotFocus
, потому что событие запускается несколько раз. Это срабатывает, когда :
- Я открываю
ComboBox
- Я провожу мышкой по предметам
- Я выбираю элемент
Более того, это может вызвать исключение stackoverflow.
Я знаю, что лучше заполнить ComboBox
анкету, прежде чем открывать ее. Я нахожусь в процедуре миграции приложений и не могу позволить себе изменить всю структуру кода.
Использование DropDownOpened
события было лучшим вариантом в моем случае.
Спасибо людям, которые помогли мне найти решение.