如何仅使用自定义对象显示DataGridView中的某些列

我有一个DataGridView,我需要添加自定义对象。 请考虑以下代码:

DataGridView grid = new DataGridView(); grid.DataSource = objects; 

使用此代码,我得到一个DataGridView对象,其所有属性都是列。 就我而言,我不想展示所有这些信息; 我想只展示两三列。 我知道我可以设置

AutoGenerateColumns = false

但我不知道如何继续进行。 一种选择是隐藏所有我不感兴趣的列,但我认为最好以相反的方式进行。 我怎样才能做到这一点?

每当我这样做时,我通常grid.DataSource作为对象上LINQ投影的结果。

所以这样的事情:

 grid.DataSource = objects.Select(o => new { Column1 = o.SomeValue, Column2 = o.SomeOtherValue }).ToList(); 

好的是,您可以将AutoGenerateColumns设置为true,这将根据投影对象的属性生成列。

编辑:

这种方法的一个缺点是,通过将所有内容投射到匿名对象中,例如,在需要访问单击事件中的特定对象的情况下,您可能会遇到问题。

在这种情况下,最好定义一个显式视图模型并将对象投影到这些模型中。 例如,

 class MyViewModel { public int Column1 { get;set; } public int Column2 { get;set; } } grid.DataSource = objects.Select(o => new MyViewModel() { Column1 = o.SomeValue, Column2 = o.SomeOtherValue }).ToList(); 

编辑2:

MyViewModel表示要在DataGridView显示的所有列。 当然应该重命名示例属性以适合您正在做的事情。 通常,ViewModel的作用是作为一种转换器,它在模型(在您的情况下是您的对象列表)和视图之间进行调解。

如果您想要保留对底层对象的引用,最好的方法可能是通过构造函数提供它:

 class MyViewModel { public int Column1 { get;set; } public int Column2 { get;set; } .... private SomeType _obj; public MyViewModel(SomeType obj) { _obj = obj; } public SomeType GetModel() { return _obj; } } grid.DataSource = objects.Select(o => new MyViewModel(o) { Column1 = o.SomeValue, Column2 = o.SomeOtherValue }).ToList(); 

我之所以选择getter方法来检索底层模型对象,只是为了避免为它生成一个列。

您也可以在底层对象的任何属性上使用Attribute [Browsable(false)],这可能是合适的。 这当然会抢占该列在其他地方可浏览,因此您可能会发现这是不受欢迎的。

您可以将数据绑定与AutoGenerateColumns = false使用,并使用DataPropertyName

 grid.Columns["Column_name_1"].DataPropertyName = "public_property_1"; grid.Columns["Column_name_2"].DataPropertyName = "public_property_2"; 

这样,只有绑定列才会显示在datagridview中,您可以根据需要在编辑器中创建列。 公共属性可以是对象中的任何公共属性。

如果要从datagridview编辑数据,则应在set方法中使用NotifyPropertyChanged。 请问我的问题/答案在哪里我一直向下解释。

你可以做这样的事情。

要首先在DataGridView显示特定列,您可以像这样在DataTable获取数据。

 String query="Your query to dispplay columns from the database"; SqlCommand cmd=new SqlCommand(query,con); //con is your Connection String con.Open(); DataTable dt=new DataTable(); SqlDataAdapter da=new SqlDataAdapter(cmd); da.Fill(dt); //Now this DataTable is having all the columns lets say /* Now take another temporary DataTable to display only particular columns*/ DataTable tempDT=new DataTable(); tempDT=dt.DefaultView.ToTable(true,"Your column name","your column name"); //Now bind this to DataGridView grid.DataSource=tempDT; con.Close(); 

我知道这是一个相当漫长的过程。那些参加表演的人可能不喜欢这样。 :P

但我觉得它运作正常。

这是我的旧项目代码。 它可以适用于您的情况。

 OleDbDataAdapter da = new OleDbDataAdapter("SELECT * FROM uyeler", baglanti); da.Fill(dbDataSet1, "uyeler"); //Set AutoGenerateColumns False dataGridView1.AutoGenerateColumns = false; //Set Columns Count dataGridView1.ColumnCount = 5; //Add Columns dataGridView1.Columns[0].Name = "İsim"; // name dataGridView1.Columns[0].HeaderText = "İsim"; // header text dataGridView1.Columns[0].DataPropertyName = "ad"; // field name dataGridView1.Columns[1].HeaderText = "Soyisim"; dataGridView1.Columns[1].Name = "Soyisim"; dataGridView1.Columns[1].DataPropertyName = "soyad"; dataGridView1.Columns[2].Name = "Telefon"; dataGridView1.Columns[2].HeaderText = "Telefon"; dataGridView1.Columns[2].DataPropertyName = "telefon"; dataGridView1.Columns[3].Name = "Kayıt Tarihi"; dataGridView1.Columns[3].HeaderText = "Kayıt Tarihi"; dataGridView1.Columns[3].DataPropertyName = "kayit"; dataGridView1.Columns[4].Name = "Bitiş Tarihi"; dataGridView1.Columns[4].HeaderText = "Bitiş Tarihi"; dataGridView1.Columns[4].DataPropertyName = "bitis"; dataGridView1.DataSource = dbDataSet1; dataGridView1.DataMember = "uyeler"; 
  SqlCommand cmd6 = new SqlCommand("SELECT * FROM tblinv WHERE invno='" + textBox5.Text + "'",cn); SqlDataReader sqlReader6 = cmd6.ExecuteReader(); if (sqlReader6.HasRows) { DataTable dt = new DataTable(); DataTable dt1 = new DataTable(); dt.Load(sqlReader6); dt1 = dt.DefaultView.ToTable(true, "ChallanNo", "ProductName", "UoM", "Price", "Qty","Subtotal"); dataGridView2.DataSource = dt1; }