I have a RadComboBox that displays a list of things from a database. Currently the list takes up to 20 seconds to load. I need this dramatically reduced. Additionally, the combo box has a text box that allows the user to search the list, and this must be included. There is another issue in that the filtering currently goes the the first instance of whatever is type in, it does not remove items from the list that do not contain the entered text. Here is the xaml,an event, the query, and the viewmodel
<telerik:RadComboBox Name="AddressesComboBox"
VerticalAlignment="Center"
HorizontalAlignment="Stretch"
MinWidth="300"
Height="75"
DropDownWidth="*"
AllowMultipleSelection="False"
TextInput="ComboBox_OnTextInput"
Text="{Binding Name, Mode=TwoWay}"
DisplayMemberPath="FullNameAndAddress"
ItemsSource="{Binding Locations}"
IsTextSearchEnabled="True"
IsFilteringEnabled="True"
OpenDropDownOnFocus="True"
SelectedValue="{Binding SelectedLocation, Mode=TwoWay}"
TabIndex="0"
IsEditable="True">
<telerik:RadComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</telerik:RadComboBox.ItemsPanel>
</telerik:RadComboBox>
private void ComboBox_OnTextInput(object sender, TextCompositionEventArgs e)
{
if (!AddressesComboBox.IsDropDownOpen)
{
AddressesComboBox.IsDropDownOpen = true;
}
}
[OperationContract]
public IList<vw_Locations> GetAddress(Guid ID, string filterString, bool activeOnly)
{
using (DispatchEntities context = new DispatchEntities())
{
string value = string.IsNullOrEmpty(filterString) ? string.Empty : filterString.ToLower();
string configValue = GetConfigurationValue(context, ID, Common.ConfigurationData.LOCATIONS_BATCH_SIZE);
int batchSize;
if (!int.TryParse(configValue, out batchSize)) batchSize = 50;
var query = from address in context.vw_addresses
where locations.ID == ID
&& (addresses.CompanyName.ToLower().Contains(value) ||
addresses.Name.ToLower().Contains(value) ||
addresses.City.ToLower().Contains(value))
orderby locations.Name
select addresses;
if (activeOnly)
{
query = from addresses in query
where addresses.IsActive == true
orderby addresses.Name
select addresses ;
}
var resultSet = query.ToList();
//var resultSet = query.Take(batchSize).ToList();
return resultSet;
}
}
public class LocationViewModel : ViewModelBase
{
private ObservableCollection<vw_addresses> _addresses;
private vw_addresses _selectedLocation;
private bool _isLoading;
public ObservableCollection<vw_addresses> addresses
{
get { return _addresses; }
set
{
_addresses = value;
OnPropertyChanged();
}
}
public vw_addresses SelectedLocation
{
get { return _selectedLocation; }
set
{
_selectedLocation = value;
OnPropertyChanged();
}
}
public bool IsLoading
{
get { return _isLoading; }
set
{
_isLoading = value;
OnPropertyChanged();
}
}
private readonly DmsServiceClient _service;
public LocationViewModel()
{
_service = ServiceLocator.Get<DmsServiceClient>();
_service.GetLocationsCompleted += ServiceOnGetLocationsCompleted;
GetData();
}
private void ServiceOnGetLocationsCompleted(object sender, GetLocationsCompletedEventArgs e)
{
try
{
addresses = new ObservableCollection<vw_addresses>(e.Result);
}
catch (Exception exception)
{
Serilog.Log.Logger.Debug(
$"ERROR: LocationViewModel.ServiceOnGetLocationsCompleted(object sender, GetLocationsCompletedEventArgs e): {exception.ToString()}");
}
IsLoading = false;
}
public void GetData()
{
IsLoading = true;
_service.GetLocationsAsync(Current.ID.Value, "", false);
}
}
In total what i need is an example or suggestion in how to turn this searchable data driven combo box into something that is faster and filters better. Thanks for the help!