I have a WPF application which shows items in a DataGrid (XCeed DataGrid). The app takes a while to load when the database (SQLite) contains lots of items, so I'd like to use yield return if possible to load these on demand. I know the XCeed DataGrid supports UI virtualization, but I'm not entirely sure how to convert the following block of synchronous code.
Currently, the list of loaded in a BackgroundWorker to prevent UI slowdown, the populated as the grid's DataSource.
public override IList<IRecipe> GetRecipes()
{
List<IRecipe> recipes = new List<IRecipe>();
Execute(conn =>
{
using (var cmd = conn.CreateCommand()) {
cmd.CommandText = "SELECT * FROM recipes ORDER BY Name";
var reader = cmd.ExecuteReader();
while (reader.Read()) {
try {
var recipe = GetRecipe(reader);
recipes.Add(recipe);
} catch (Exception ex) {
Console.WriteLine(string.Format("Error loading recipe: {0}", ex.Message));
}
}
reader.Close();
cmd.CommandText = "SELECT * FROM Ingredients WHERE Recipe = @Recipe";
cmd.Parameters.AddWithValue("@Recipe", string.Empty);
foreach (IRecipe recipe in recipes) {
cmd.Parameters["@Recipe"].Value = recipe.ID;
reader = cmd.ExecuteReader();
while (reader.Read()) {
try {
IIngredient Ingredient = GetIngredient(reader);
recipe.Ingredients.Add(Ingredient);
} catch (Exception ex) {
Console.WriteLine(string.Format("Error adding Ingredient to recipe '{0}': {1}", recipe.Name, ex.Message));
}
}
reader.Close();
}
}
Alternatively is there any other way I could improve the speed and use lazy loading?
I'm not familiar exactly with how xceed fetches the virtualized items.
I assume it is by some kind of event that specifies what range of rows that are requested.
In the event (or whatever method that is used) you fetch a range of your query. Use LIMIT
and OFFSET
as noted at the bottom of the SELECT
documentation.