Jimmyt1988
Jimmyt1988

Reputation: 21126

Slow showing / drawing dialogue with ListBox?

My application uses entity framework to pull in a small tiny set of results... It takes about 3 seconds for it to do it? Why might this be?

Start.cs

...
private void projectToolStripMenuItem_Click(object sender, System.EventArgs e)
{
    NewProject newProjectForm = new NewProject();
    newProjectForm.ShowDialog(); // It seems to take about 3 or 4 seconds to actually get to this :S
}
...

NewProject.cs

public partial class NewProject : Form
{
    private EFProjectTypeRepository projectTypeRepository;

    public NewProject()
    {
        projectTypeRepository = new EFProjectTypeRepository();

        InitializeComponent();
        ListBoxProjectTypes();
    }

    public void ListBoxProjectTypes()
    {    
        DateTime then = DateTime.Now;

        // PreLoadedResources.projectTypes is a preloaded resource which takes split seconds to load.

        ListBoxProjectType.Items.AddRange(PreLoadedResources.projectTypes.Select(item => (object)item.Title).ToArray()); // If I comment this line out, the dialogue is almost instant @ timeTaken  {00:00:00.0010019}

        DateTime now = DateTime.Now;
        TimeSpan timeTaken = now.Subtract(then); 
    }
}

:

timeTaken   {00:00:02.4261369}  System.TimeSpan

when I go and show the dialogue a second time, it's instant!

My listbox shows 1 item so far lol.

Notes:

public static class PreLoadedResources
{
    public static IEnumerable<ProjectType> projectTypes;
}

Upvotes: 0

Views: 150

Answers (3)

Jimmyt1988
Jimmyt1988

Reputation: 21126

Changing my IEnumerable to IList made a difference:

public static class PreLoadedResources
{
    public static IEnumerable<ProjectType> projectTypes;
}

to

public static class PreLoadedResources
{
    public static IList<ProjectType> projectTypes;
}

then in my loading (which takes a 2 second hit), I just .ToList it instead... but now the showdialogue procedure takes split seconds.

Upvotes: 0

itsme86
itsme86

Reputation: 19486

The ListBox has to redraw every time you add an item. You can either use Dmitry's method of using AddRange(), or you can wrap your loop with BeginUpdate()/EndUpdate() calls.

ListBoxProjectType.BeginUpdate();

foreach( var projectType in projectTypes )
{
    ListBoxProjectType.Items.Add(projectType.Title);
}

ListBoxProjectType.EndUpdate();

Upvotes: 1

Dmitry
Dmitry

Reputation: 14059

Try to replace adding individual items to listbox with AddRange:

public void ListBoxProjectTypes()
{
    IEnumerable<ProjectType> projectTypes = projectTypeRepository.ProjectTypes;
    ListBoxProjectType.Items.AddRange(projectTypes.Select(item => (object)item.Title).ToArray());
}

Or simply wrap items adding with ListBoxProjectType.BeginUpdate and ListBoxProjectType.EndUpdate.

Upvotes: 0

Related Questions