在c#中完成组合框数据加载后加载Windows窗体

时间:2017-07-04 11:40:10

标签: c# winforms asynchronous combobox async-await

我有一个名为frmEmployees的员工form,我需要在其中加载几个combo box数据,例如国家/地区,类别,国籍等。

现在,当用户点击打开frmEmployees时,窗口会被卡住,然后打开。我认为这是因为数据加载和初始化combo box。 现在!我想要的是,只需点击按钮打开frmEmployees运行进度条直到数据加载完成然后打开表单。

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

        LoadComboboxDS();
    }

我也试过

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));

    }

2 个答案:

答案 0 :(得分:0)

您可以使用Entity Framework 6的Async扩展方法使您的代码异步。

首先分开您的数据访问和表示层:

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();
        }
    }
}

然后,您可以立即运行所有这些任务并等待它们完成:

// 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
}

现在,您只需要让表单接受构造函数中的完整数据,而不是让表单加载这些打破抽象的数据:

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.
    }
}

一件重要的事情:您可以将许多任务和许多数据传递给表单构造函数。如果要经常使用所有这些数据,那么您可能希望将这个“获取所有这些东西”逻辑封装到一个地方以删除可能的代码重复。

答案 1 :(得分:0)

看看我做了什么......如果有人可以查看我的代码,那将是可观的。

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);
        }
    }