简体   繁体   中英

Load Windows form after complete combobox data load in c#

I have a form for employees called frmEmployees where I need to load couple of combo box with data like country, category, nationality, such others.

Now when user click on to open frmEmployees, window is stuck for bit and then open. I assume that this is because of data loading and initializing the combo box . Now! what I want is, just after click on button to open frmEmployees run a progress bar till data loading complete and then open form.

public frmEmployee()
    {
        InitializeComponent();
        con = new Connection();

        LoadComboboxDS();
    }

I have tried also

private void FrmEmployee_Load(object sender, EventArgs e)
    {
        LoadComboboxDS();
    }



private void LoadComboboxDS()
    {
        //company
        var _companies = con.Companies.Where(x => x.IsDeleted == false).ToList();
        _companies.Insert(0,new data.Models.CompanyModels.Company { Address = new data.Models.Address(), Code = null, Name = "--Select--", BaseCurrency = new data.Models.Currency() });
        cbCompany.DataSource = _companies;
        cbCompany.DisplayMember = "Name";
        cbCompany.ValueMember = "ID";

        //gender
        cbGender.DataSource = Enum.GetValues(typeof(Gender));

        //merital status
        cbMeritalStatus.DataSource = Enum.GetValues(typeof(MaritalStatus));

        //citizenship
        var _citizenships = con.Countries.Select(x => x.Citizenship).Distinct().ToList();
        _citizenships.Insert(0, "--Select--");
        cbCitizenship.DataSource = _citizenships;
        cbCitizenship.DisplayMember = "Citizenship";

        //nationality
        var _nations = con.Countries.Select(x => x.Name).Distinct().ToList();
        _nations.Insert(0, "--Select--");
        cbNationality.DataSource = _nations;
        cbNationality.DisplayMember = "Name";

        //domicile
        var _domiciles = con.Countries.Select(x => x.Name).Distinct().ToList();
        _domiciles.Insert(0, "--Select--");
        cbDomicile.DataSource = _domiciles;
        cbDomicile.DisplayMember = "Name";

        //cast category
        var _casts = con.CastCategories.Select(x => new {x.ShortText, x.Description}).Distinct().ToList();
        _casts.Insert(0, new { ShortText = "", Description = "--Select--" });
        cbCategory.DataSource = _casts;
        cbCategory.DisplayMember = "Description";
        cbCategory.ValueMember = "ShortText";

        //religion 
        cbReligion.DataSource = Enum.GetValues(typeof(Religion));

    }

You can use Async extension methods of Entity Framework 6 to make your code asynchronous.

Separate your data access and presentation layer, at first:

public static class MyRepository // consider not static, just an example
{
    public static async Task<List<Company>> GetCompanies()
    {
        using (var connection = new Connection()) // consider factory
        {
            return await con.Companies.Where(x => x.IsDeleted == false).ToListAsync();
        }
    }

    public async Task<List<Citizenship>> GetCitizenships()
    {
        using (var connection = new Connection()) // factory?
        {
            return await con.Countries.Select(x => x.Citizenship).Distinct().ToList();
        }
    }
}

Then, you can run all these tasks at once and wait for them to complete:

// Wherever you are going to open frmEmployee
public async Task openFrmEmployee_OnClick(object sender, EventArgs e)
{
    var getCompaniesTask = MyRepository.GetCompanies();
    var getCitizenshipsTask = MyRepository.GetCitizenships();

    await Task.WhenAll(getCompaniesTask, getCitizenshipsTask); // UI thread is not blocked

    var form = new FrmEmployee(getCompaniesTask.Result, getCitizenshipsTask.Result); // form is created with data
}

Now, you only need to make your form accept complete data in constructor instead of making your form load this data which breaks abstraction:

public class FrmEmployees
{
    public FrmEmployees(List<Company> companies, List<Citizenship> citizenships)
    {
        companies.Insert(0,new data.Models.CompanyModels.Company { Address = new data.Models.Address(), Code = null, Name = "--Select--", BaseCurrency = new data.Models.Currency() });
        cbCompany.DataSource = companies;
        cbCompany.DisplayMember = "Name";
        cbCompany.ValueMember = "ID";

        citizenships.Insert(0, "--Select--");
        cbCitizenship.DataSource = _citizenships;
        cbCitizenship.DisplayMember = "Citizenship";

        // etc.
    }
}

One important thing: you can get many tasks and many data passed to a form constructor. If all this data is going to be used often togetther, then you would probably want to encapsulate this "get all these things" logic into a single place to remove possible code duplication.

See what I have done... if anyone can review my code it would be appreciable.

public class EmployeeFormDataRepesenter
{
    public List<Company> Companies { get; set; }
    public List<Country> Countries { get; set; }
    public List<CastCategory> CastCategories { get; set; }
}

public void LoadData(EmployeeFormDataRepesenter representer)
    {

        //gender
        cbGender.DataSource = Enum.GetValues(typeof(Gender));
        //merital status
        cbMeritalStatus.DataSource = Enum.GetValues(typeof(MaritalStatus));
        //religion 
        cbReligion.DataSource = Enum.GetValues(typeof(Religion));

        //company
        var _companies = representer.Companies;
        _companies.Insert(0, new data.Models.CompanyModels.Company { Address = new data.Models.Address(), Code = null, Name = "--Select--", BaseCurrency = new data.Models.Currency() });
        cbCompany.DataSource = _companies;
        cbCompany.DisplayMember = "Name";
        cbCompany.ValueMember = "ID";

        //citizenship
        var _citizenships = representer.Countries.Select(x => x.Citizenship).ToList();
        _citizenships.Insert(0, "--Select--");
        cbCitizenship.DataSource = _citizenships;
        cbCitizenship.DisplayMember = "Citizenship";

        //nationality
        var _nations = representer.Countries.Select(x => x.Name).ToList();
        _nations.Insert(0, "--Select--");
        cbNationality.DataSource = _nations;
        cbNationality.DisplayMember = "Name";

        //domicile
        var _domiciles = representer.Countries.Select(x => x.Name).ToList();
        _domiciles.Insert(0, "--Select--");
        cbDomicile.DataSource = _domiciles;
        cbDomicile.DisplayMember = "Name";

        //cast category
        var _casts = representer.CastCategories.Select(x => new { x.ShortText, x.Description }).Distinct().ToList();
        _casts.Insert(0, new { ShortText = "", Description = "--Select--" });
        cbCategory.DataSource = _casts;
        cbCategory.DisplayMember = "Description";
        cbCategory.ValueMember = "ShortText";
    }




private async void btnEmplyee_Click(object sender, EventArgs e)
    {
        con = new Connection();
        Action showProgress = () => frmStatrup._progressBar.Visible = true;
        Action hideProgress = () => frmStatrup._progressBar.Visible = false;

        EmployeeFormDataRepesenter representer;

        Task<List<Company>> _taskCompany = new Task<List<Company>>(() =>
        {
            BeginInvoke(showProgress);
            var list = con.Companies.ToListAsync();
            BeginInvoke(hideProgress);
            if (list != null)
                return list.Result;
            return null;
        });

        Task<List<Country>> _taskCountry = new Task<List<Country>>(() =>
        {
            BeginInvoke(showProgress);
            var list = con.Countries.ToListAsync();
            BeginInvoke(hideProgress);
            if (list != null)
                return list.Result;
            return null;
        });

        Task<List<CastCategory>> _taskCasts = new Task<List<CastCategory>>(() =>
        {
            BeginInvoke(showProgress);
            var list = con.CastCategories.ToListAsync();
            BeginInvoke(hideProgress);
            if (list != null)
                return list.Result;
            return null;
        });


        _taskCompany.Start();
        var _companies = await _taskCompany;

        _taskCountry.Start();
        var _countries = await _taskCountry;

        _taskCasts.Start();
        var _casts = await _taskCasts;


        if (_companies.Count != 0)
        {
            representer = new EmployeeFormDataRepesenter();
            representer.Companies = _companies;
            representer.Countries = _countries;
            representer.CastCategories = _casts;
        }
        else
        {
            representer = null;
        }

        if (representer != null)
        {
            frmEmployee _emp = new frmEmployee();
            _emp.LoadData(representer);
            Functions.OpenForm(_emp, this.ParentForm);
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM