2013-09-04 4 views
1

Таблица данных в следующем коде заполняется записями 7500- +. Все это быстро загружается с сервера. Проблема в том, что требуется некоторое время, чтобы перебирать строки данных, чтобы добавить их в поле со списком. Есть ли альтернативный способ установки источника данных в поле со списком или способ ускорения этого процесса?Самый быстрый способ заполнения combobox из datatable в VB.Net

 Dim dtColours As New DataTable 
     Dim daColours As New SqlDataAdapter 
     Dim i As Integer 

     ConnectToSQL() 
     daColours = New SqlDataAdapter("SELECT DISTINCT Rtrim(UPPER(Colour)) As Colour FROM invStockColour WHERE InUse = 1 ORDER BY Colour", dbSQL) 
     daColours.Fill(dtColours) 

     For i = 0 To dtColours.Rows.Count - 1 
      cboColours.Items.Add(dtColours.Rows(i).Item(0).ToString) 
     Next 

     dbSQL.Close() 
+1

Это похоже на хороший способ добавления данных. 7500+ элементов в ComboBox звучит слишком много. Может быть, вы можете разделить информацию и загрузить в выпадающие списки меньше данных в зависимости от пользовательских значений выбора в другом поле со списком или что-то вроде этого? – SysDragon

ответ

7

голодном способом было бы использовать метод AddRange вместо использования Add, что-то вроде:

Dim items = dtColours.AsEnumerable().Select(Function(d) DirectCast(d(0).ToString(), Object)).ToArray() 
cboColours.Items.AddRange(items) 

Я сделал простую проверку, и использование AddRange в ~ 3 раза быстрее, чем с использованием Add.

Конечно, выделение массива и заполнение его контуром For, вероятно, на несколько миллисекунд быстрее, чем использование Linq.

+0

Кажется, вы правы. И поскольку вы уже учитываете часть LINQ, я думаю, что я лучше удалю свой ответ. – varocarbas

+0

PS: относительно вашего последнего изменения: я не являюсь поклонником LINQ (чаще всего предпочитаю цикл), но в этом контексте (нечетко большой DataTable) я бы пошел на LINQ. – varocarbas

+2

@varocarbas Linq очень приятный, но синтаксис анонимных методов в VB.Net является soooooo уродливым :-) – sloth

-1

Попробуйте это:

cboColours.DataSource = dtColours 'For Windows Forms или

cboColours.ItemsSource = dtColours 'For WPF

+1

Во-первых, вы должны упомянуть такие вещи, как DisplayMember и ValueMember, когда предлагается установить источник данных. В дополнение к этому, это работает не быстрее, чем то, что я сейчас делаю. –

2
Dim daColours As New SqlDataAdapter("SELECT DISTINCT Rtrim(UPPER(Colour)) As Colour FROM invStockColour WHERE InUse = 1 ORDER BY Colour", dbSQL) 

Dim dtColours As New DataTable 
daColours.Fill(dtColours) 

cboColours.DataSource=dtColours 
cboColours.DisplayMember="Colour" 
+0

, пожалуйста, объясните, как ваш код достигает цели, к которой стремится OP. это может показаться вам очевидным и другими опытными программистами. Если вы дадите четкое объяснение своего кода, это приведет к лучшим ответам на SO, а также более upvotes – Malachi

3

Вы также можете привязать свойство DataSource ComboBox к DataTable. Это имеет дополнительное преимущество для привязки других данных столбца (таких как значения ключей, которые вы, возможно, не хотите видеть пользователю).

Вы должны иметь возможность вернуть объект DataTable из своего SQLAdapter.

cboColours.DataSource = dtColours 
cboColours.DisplayMember = dtColours.Columns("Colour").ToString 
cboColours.ValueMember = dtColours.Columns("Colour_id").ToString 
+0

Я предпочитаю этот метод, поскольку я имею дело исключительно с классами, возвращающими данные. Этот метод также позволяет мне установить выбранное значение из скрытого индекса внутри flexgrid в методе Click. –

+0

Элемент управления будет связываться при установке DataSource. Установка ValueMember после DataSource заставит элемент управления связываться снова. Так быстро, как могло бы быть. DataSource должен быть установлен после ValueMember. – Padhraic

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