将ComboBox列添加到现有DataTable DataGridView

时间:2016-08-05 21:29:54

标签: c# winforms

我有一个现有的数据网格视图,其DataSource是一个数据表,我从一个自定义对象列表中填充。

private myDataTable = new DataTable();

List<SomeObjectModel> dataSource = (from e in queryResults
    select
        new SomeObjectModel
        {
            Id = e.Id,
            Priority = e.Name,
            Channel = e.Channel
        }).ToList();

myDataTable = ToDataTable(dataSource); //See method below
dataGridView.DataSource = myDataTable;

从上一个关于StackOverflow的问题,我发现我在那里使用的ToDataTable方法可以使用Reflection将我的对象列表转换为DataTable:

    public static DataTable ToDataTable<T>(List<T> items)
    {
        DataTable dataTable = new DataTable(typeof(T).Name);
        PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

        foreach (PropertyInfo prop in Props)
        {
                dataTable.Columns.Add(prop.Name);
        }

        foreach (T item in items)
        {
            var values = new object[Props.Length];
            for (int i = 0; i < Props.Length; i++)
            {
                values[i] = Props[i].GetValue(item, null);
            }
            dataTable.Rows.Add(values);
        }

        dataTable.AcceptChanges();

        return dataTable;
    }

这适用于我的所有DataGridViewTextBox列。现在,我想将一个名为“Person”的新DataGridViewComboBoxColumn添加到数据网格中,该数据网格具有ValueMember =“PersonId”和从Person对象列表填充的DisplayMember =“PersonName”。

我在这里遇到了解如何从数据表中将这种类型的列添加到数据网格中。

My Person对象再次具有PersonId和PersonName属性,我想将其用作组合框的ValueMember和DisplayMember。

我被困住了,但我的想法是: 1.)更新SomeObjectModel以包含Person, 2.)更新ToDataTable方法以包含一个if子句,以便在项目名称为“Person”时捕获,但我不确定如何为行做什么。另外,简单地查找属性名称会感觉很麻烦,因为我想保持ToDataTable干净。

 public static DataTable ToDataTable<T>(List<T> items)
    {
        DataTable dataTable = new DataTable(typeof(T).Name);
        PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

        foreach (PropertyInfo prop in Props)
        {
           if (prop.Name = "Person") { // Create DataGridViewComboBoxColumn } 

            else
            {
                dataTable.Columns.Add(prop.Name);
            }

        }

        foreach (T item in items)
        {
            var values = new object[Props.Length];
            for (int i = 0; i < Props.Length; i++)
            {
                values[i] = Props[i].GetValue(item, null);
            }

            dataTable.Rows.Add(values);
        }

        dataTable.AcceptChanges();

        return dataTable;
    }

1 个答案:

答案 0 :(得分:0)

以下是我过去为此做过的一个例子...简单的表格,下拉列表中加载了&#34;人员&#34;名单。根据您拥有的标准进行过滤的按钮...希望它有所帮助。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private class Person
        {
            public int PersonId { get; set; }
            public string Name { get; set; }
        }

        private class Course
        {
            public int CourseId { get; set; }
            public string CourseName { get; set; }
            public int ProfessorId { get; set; }
        }

        private List<Course> courses = new List<Course>();
        private List<Person> professors = new List<Person>();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            courses.Add(new Course { CourseId = 1, CourseName = "Math", ProfessorId = 1 });
            courses.Add(new Course { CourseId = 2, CourseName = "English", ProfessorId = 2 });
            courses.Add(new Course { CourseId = 3, CourseName = "History", ProfessorId = 1 });

            professors.Add(new Person { PersonId = 1, Name = "John Doe" });
            professors.Add(new Person { PersonId = 2, Name = "Jane Doe" });

            cboProfessors.DisplayMember = "Name";
            cboProfessors.ValueMember = "PersonId";
            cboProfessors.DataSource = professors;

            grdCourses.AutoGenerateColumns = false;
            grdCourses.Columns.Add(new DataGridViewTextBoxColumn { Name = "CourseId", HeaderText = "Course ID #", DataPropertyName="CourseId" });
            grdCourses.Columns.Add(new DataGridViewTextBoxColumn { Name = "Name", HeaderText = "Course Name", DataPropertyName="CourseName" });
            grdCourses.Columns.Add(new DataGridViewComboBoxColumn { Name = "Professor", HeaderText = "Professor", DataSource = professors,
                DisplayMember = "Name", ValueMember = "PersonId", DataPropertyName="ProfessorId" });

            grdCourses.DataSource = courses;
        }

        private void btnFilter_Click(object sender, EventArgs e)
        {
            int professorId = (int)cboProfessors.SelectedValue;
            List<Course> filteredCourses = courses.Where(x => x.ProfessorId == professorId).ToList();
            grdCourses.DataSource = filteredCourses;
        }
    }
}