2015-02-28 4 views
0

У меня возникли проблемы с загрузкой datagridview с двумя столбцами. Форма с Datagridview и 1 кнопка.Заполнение datagridview winforms .net 4.0

отдел (текст) EmployeesByDpt (Combo)

У меня есть форма с DataGridView и Button (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; 
    } 
} 
+0

Привет, спасибо за ваш ответ «Databind», похоже, не является методом на datagridview. – developer9969

+0

В winforms нет databind – developer9969

+1

@MethodMan это приложение WinForms, не нужно иметь метод DataBind – Steve

ответ

0

Запуск точный код, я столкнулся с несколькими проблемами. Следующее объяснение покажет вам, что я сделал, чтобы исправить каждую последующую проблему, но с предупреждением: в конце я не смог сделать выбор из ComboBox без изменения метода привязки между DataGridView и Departments и удаления некоторого предоставленного кода.

ArgumentException выброшен для каждой строки

Каждая строка бросает исключение: "значение DataGridViewComboBoxCell не является действительным." Changing следующая строка исправил:

colComboEmployeesByDpt.DataPropertyName = "Employees"; 

в

colComboEmployeesByDpt.DataPropertyName = "Employee"; 

Пустые ComboBoxes

Теперь вы заметите, что 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 пункты списки всегда были пусты, поэтому выбранное значение было «недействителен».)

Ответ - Restructure

Чтобы заставить его работать, я сделал несколько ключевых изменений.Я полностью упал следующее:

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

Это решение сработало для меня. Когда у меня будет свободное время, я продолжу изучать исправление своего оригинального решения с той точки, которая меня беспокоила. Надеюсь, теперь это поможет.

Смежные вопросы