【问题标题】:Load Windows form after complete combobox data load in c#在 C# 中完成组合框数据加载后加载 Windows 窗体
【发布时间】:2017-07-04 11:40:09
【问题描述】:

我有一个名为 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));

    }

【问题讨论】:

  • 您应该为进度条使用后台工作程序。更简单的方法是将光标图标更改为加载符号。
  • 你能推荐任何示例代码吗?因为我尝试了一些但没有运气
  • @kurdy Backgroundworker 不适用于 UI 元素。 UI 控件需要在 UI 线程中加载。
  • 没错@Harsh
  • 你使用什么 ORM?

标签: c# winforms asynchronous combobox async-await


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多