簡體   English   中英

填充datagridview winforms .net 4.0

[英]Populating datagridview winforms .net 4.0

我在使用2列加載datagridview時遇到問題。 表格帶有Datagridview和1個按鈕。

部門(文字)EmployeesByDpt(Combo)

我有一個帶有datagridview和Button(Load)的表單,當我按下load時,應該填充datagridview。 單擊Employee Combo應顯示屬於特定部門的所有員工。

我似乎無法讓它工作,下面就是我所做的,

有什么建議嗎?目前沒什么可說的。 謝謝

代碼(為了簡單起見,我把所有內容放在一起)

     public partial class Form2 : Form
{
    Repository repository;
    readonly DataGridViewTextBoxColumn colDepartment=new DataGridViewTextBoxColumn();
    readonly DataGridViewComboBoxColumn colComboEmployeesByDpt = new DataGridViewComboBoxColumn();
    public Form2()
    {
        InitializeComponent();
        repository = new Repository();
        SetupDataGridView();
    }

    private void SetupDataGridView()
    {
        dataGridView1.EditingControlShowing += OnEditingControlShowing;
        dataGridView1.CellValueChanged += OnCellsValueChanged;
        dataGridView1.AutoGenerateColumns = false;

        colDepartment.DataPropertyName = "Name";
        colDepartment.HeaderText = "Department Name";

        colComboEmployeesByDpt.DataPropertyName = "Employees";
        colComboEmployeesByDpt.HeaderText = "Employees";
        colComboEmployeesByDpt.DisplayMember = "FullName";
        //colComboEmployeesByDpt.DataSource = "FullName";


        dataGridView1.Columns.AddRange(new DataGridViewColumn[] { colDepartment ,colComboEmployeesByDpt});
    }

    private void OnCellsValueChanged(object sender, DataGridViewCellEventArgs e)
    {

    }

    private void OnEditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
    {
        if (dataGridView1.CurrentCell.ColumnIndex == colDepartment.Index)
        {
            var control = e.Control as DataGridViewComboBoxEditingControl;
            if (control != null)
            {
                var bs = control.DataSource as BindingSource;
                if (bs != null)
                {
                    var comboBox = e.Control as ComboBox;
                    BindingList<Employee> employees = repository.GetEmployeeByDepartments(control.Text);
                    comboBox.DataSource = employees;
                    object employeeValue = dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Cells[colComboEmployeesByDpt.Index].Value;
                    if (employeeValue == DBNull.Value || employeeValue == null)

                    if (dataGridView1.CurrentCell.Value != DBNull.Value && dataGridView1.CurrentCell.Value != null)
                    {
                        control.SelectedValue = dataGridView1.CurrentCell.Value;
                    }
                }
            }
        }
    }

    private void btnLoad_Click(object sender, EventArgs e)
    {

        BindingList<Department> departments = repository.GetDepartments();

        dataGridView1.DataSource = departments;
        dataGridView1.Refresh();

    }
}

public class Department
{
    public Department()
    {
        Employees=new BindingList<Employee>();
    }
    public string Name { get; set; }
    public BindingList<Employee> Employees { get; set; }
}

public class Employee
{
    public string FullName { get; set; }
}

public class Repository
{
    public BindingList<Department> GetDepartments()
    {
        var departments=new BindingList<Department>();
        departments.Add(new Department{Name = "Food"});
        departments.Add(new Department{Name = "Travel"});
        departments.Add(new Department{Name = "Beauty"});
        return departments;
    }
    public BindingList<Employee> GetEmployeeByDepartments(string name)
    {
        var employees = new BindingList<Employee>();
        switch (name)
        {
            case "Food":
                employees.Add(new Employee { FullName = "Jim Bloggs1" });
                employees.Add(new Employee { FullName = "Jim Bloggs2" });
                break;
            case "Travel":
                employees.Add(new Employee { FullName = "Marc Smith1" });
                employees.Add(new Employee { FullName = "Marc Smith2" });
                break;
            case "Beauty":
                  employees.Add(new Employee { FullName = "Mario XXX1" });
                  employees.Add(new Employee { FullName = "Mario XXX2" });
                break;

        }

        return employees;
    }
}

運行您的確切代碼,我遇到了幾個問題。 下面的解釋將向您展示我為解決每個后續問題所做的工作,但有一個警告:最后,我無法在不更改DataGridViewDepartments之間的綁定方法並刪除一些提供的代碼的情況下從ComboBox進行選擇。

為每一行拋出ArgumentException

每行拋出異常: “DataGridViewComboBoxCell值無效。” 更改以下行修復此問題:

colComboEmployeesByDpt.DataPropertyName = "Employees";

colComboEmployeesByDpt.DataPropertyName = "Employee";

空組合框

現在你會注意到ComboBox都是空的。 在事件處理程序OnEditingControlShowing ,第一個if statement應該檢查colComboEmployeesByDpt.Index而不是colDepartment.Index 但這還不夠,因為if (bs != null)總是假的。 即使修復該檢查, control.Text也總是空的。 相反,嘗試:

BindingList<Employee> employees = repository.GetEmployeeByDepartments(this.dataGridView1.CurrentRow.Cells[colDepartment.Index].Value.ToString());

有了這個,您將看到每個ComboBox都有正確的員工姓名列表。 但是, ArgumentException已返回。 盡我所能,這次我無法修復它。 (我懷疑ComboBox項目列表始終為空,因此所選值為“無效” 。)

答案 - 重組

為了讓它工作,我做了幾個核心的改變。 我完全放棄了以下內容:

colComboEmployeesByDpt.DisplayMember = "FullName";

private void OnEditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
  ...
}

然后我添加了一個公共屬性來記住Departments,手動綁定每一行的員工,並在部門名稱更改時連接OnCellsValueChanged以刷新列表:

BindingList<Department> Departments { get; set; }

private void OnCellsValueChanged(object sender, DataGridViewCellEventArgs e)
{
  if (e.ColumnIndex == colDepartment.Index)
  {
    this.Departments[e.RowIndex].Employees = repository.GetEmployeeByDepartments(this.dataGridView1.CurrentCell.EditedFormattedValue.ToString());
    DataGridViewComboBoxCell cell = (DataGridViewComboBoxCell)this.dataGridView1.CurrentRow.Cells[colComboEmployeesByDpt.Index];
    cell.DataSource = this.Departments[e.RowIndex].Employees;
  }
}

private void btnLoad_Click(object sender, EventArgs e)
{
  //this.dataGridView1.Rows.Clear(); // Needed if the button can be clicked repeatedly.
  this.Departments = repository.GetDepartments();

  foreach (Department department in this.Departments)
  {
    department.Employees = repository.GetEmployeeByDepartments(department.Name);

    DataGridViewRow row = (DataGridViewRow)(dataGridView1.Rows[0].Clone());

    DataGridViewTextBoxCell textCell = (DataGridViewTextBoxCell)(row.Cells[0]);
    textCell.Value = department.Name;

    DataGridViewComboBoxCell comboCell = (DataGridViewComboBoxCell)(row.Cells[1]);
    comboCell.DataSource = department.Employees;
    comboCell.DisplayMember = "FullName";

    dataGridView1.Rows.Add(row);
  }
}

這個解決方案對我有用。 當我有空閑時間時,我將繼續從困難的地方開始研究修復原始解決方案。 希望現在有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM