【问题标题】:Populating datagridview winforms .net 4.0填充datagridview winforms .net 4.0
【发布时间】:2015-02-28 17:18:07
【问题描述】:

我在加载具有 2 列的 datagridview 时遇到问题。 带有 Datagridview 和 1 个按钮的表单。

部门(文字) EmployeesByDpt(组合)

我有一个带有 datagridview 和按钮(加载)的表单,当我按下加载时,应该填充 datagridview。 单击员工组合应显示属于特定部门的所有员工。

我似乎无法让它工作,以下是我所做的,

有什么建议吗?目前没有任何显示。谢谢

代码(为了简洁起见,我将所有代码放在一起)

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

【问题讨论】:

  • 您好,感谢您的回复“Databind”似乎不是datagridview上的方法。
  • winforms中没有databind
  • @MethodMan 它是一个 WinForms 应用程序,不需要有 DataBind 方法
  • 对不起..我还以为是网络表单..

标签: c# datagridview


【解决方案1】:

运行您的确切代码,我遇到了几个问题。以下解释将向您展示我为解决每个后续问题所做的工作,但带有警告:最后,如果不更改 DataGridViewDepartments 之间的绑定方法,我无法从 ComboBox 中进行选择删除一些提供的代码。

每行抛出ArgumentException

每一行都抛出异常:“DataGridViewComboBoxCell 值无效。”更改以下行修复了此问题:

colComboEmployeesByDpt.DataPropertyName = "Employees";

colComboEmployeesByDpt.DataPropertyName = "Employee";

空组合框

现在您会注意到 ComboBoxes 都是空的。在事件处理程序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 项目列表总是空的,所以选择的值是“invalid”。)

答案 - 重组

为了让它发挥作用,我进行了几项核心更改。我完全放弃了以下内容:

colComboEmployeesByDpt.DisplayMember = "FullName";

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

然后我添加了一个公共属性来记住部门,手动绑定每一行的员工,并在部门名称更改时连接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);
  }
}

这个解决方案对我有用。当我有空闲时间时,我将继续从让我难过的地方着手修复您的原始解决方案。希望这对现在有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-08
    • 2017-01-24
    • 2019-11-02
    • 1970-01-01
    • 2019-07-21
    • 2011-03-12
    • 1970-01-01
    相关资源
    最近更新 更多