C# 如何使用自定义对象仅显示 DataGridView 中的某些列
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14793990/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to show only certain columns in a DataGridView with custom objects
提问by Cristhian Boujon
I have a DataGridView and I need to add custom objects to it. Consider the following code:
我有一个 DataGridView,我需要向它添加自定义对象。考虑以下代码:
DataGridView grid = new DataGridView();
grid.DataSource = objects;
With this code I get a DataGridView object with all properties as columns. In my case, I don't want to show all of this information; I want to show just two or three columns. I know that I can set
通过这段代码,我得到了一个 DataGridView 对象,所有属性都作为列。就我而言,我不想显示所有这些信息;我只想显示两列或三列。我知道我可以设置
AutoGenerateColumns = false
.
AutoGenerateColumns = false
.
But I do not know how to proceed afterwards. One option is to hide all columns that do not interest me, but I think it would be better to do it in the opposite way. How can I do this?
但我不知道之后如何进行。一种选择是隐藏我不感兴趣的所有列,但我认为最好以相反的方式进行。我怎样才能做到这一点?
采纳答案by nick_w
Whenever I do this I usually make grid.DataSource
the result of a LINQ projection on the objects.
每当我这样做时,我通常会grid.DataSource
在对象上制作LINQ 投影的结果。
So something like this:
所以像这样:
grid.DataSource = objects.Select(o => new
{ Column1 = o.SomeValue, Column2 = o.SomeOtherValue }).ToList();
The nice thing is that you can then set AutoGenerateColumns
to true, which will generate columns based on the properties of the projected objects.
好消息是,您可以将其设置AutoGenerateColumns
为 true,这将根据投影对象的属性生成列。
Edit:
编辑:
The one downside to this approach is that by projecting everything into an anonymous object, you can have problems in situations where you need to access a specific object in a click event, for example.
这种方法的一个缺点是,通过将所有内容投影到匿名对象中,例如,在需要访问单击事件中的特定对象的情况下,您可能会遇到问题。
In this case you may be better off defining an explicit view model and projecting your objects into those. E.g.,
在这种情况下,您最好定义一个明确的视图模型并将您的对象投影到这些模型中。例如,
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();
Edit 2:
编辑2:
MyViewModel
represents all of the columns you want to display in the DataGridView
. The example properties should of course be renamed to suit what you are doing. In general, the point of a ViewModel is to serve as a sort of converter that mediates between the model (in your case your list of objects) and the view.
MyViewModel
表示要在DataGridView
. 示例属性当然应该重命名以适合您的操作。一般来说, ViewModel 的作用是充当一种在模型(在您的情况下是您的对象列表)和视图之间进行调解的转换器。
If you are wanting to retain a reference to the underlying object, the best way might be to supply it via the constructor:
如果您想保留对底层对象的引用,最好的方法可能是通过构造函数提供它:
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();
The reason I have gone for a getter method to retrieve the underlying model object is simply to avoid a column being generated for it.
我使用 getter 方法来检索底层模型对象的原因只是为了避免为其生成列。
回答by John
You can also use Attribute [Browsable(false)] on any property in the underlying Objects, as may be appropriate. This of course would preempt the column from being browse-able some other place, so you might find that undesirable.
您还可以在适当的情况下对底层对象中的任何属性使用属性 [Browsable(false)]。这当然会抢占该列在其他地方可浏览的权限,因此您可能会发现这是不可取的。
回答by Alejandro del Río
You can use databindings with AutoGenerateColumns = false
and using DataPropertyName like this
您可以AutoGenerateColumns = false
像这样使用数据绑定和使用 DataPropertyName
grid.Columns["Column_name_1"].DataPropertyName = "public_property_1";
grid.Columns["Column_name_2"].DataPropertyName = "public_property_2";
This way only bound columns will be shown in the datagridview, and you can create the columns in the editor if you want. Public properties can be any public attribute within your object.
这样,datagridview 中只会显示绑定的列,如果需要,您可以在编辑器中创建列。公共属性可以是对象中的任何公共属性。
If you are editing your data from the datagridview, then you should use NotifyPropertyChanged in the set methods. Se my question/answer herewhere I explain this all the way down.
如果您正在从 datagridview 编辑数据,那么您应该在 set 方法中使用 NotifyPropertyChanged。在这里我一直解释我的问题/答案。
回答by Sujith H S
You can do something like this.
你可以做这样的事情。
To display only particluar columns in a DataGridView
first you take the data in a DataTable
like this.
要首先仅显示特定的列,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();
I know this is a quite long process.Those who go for the performance might not like this. :P
我知道这是一个很长的过程,喜欢表演的人可能不喜欢这样。:P
But i think it works fine.
但我认为它工作正常。
回答by Ahmet U?ur
This is my code from an old project. It can work for your case.
这是我的旧项目代码。它可以适用于您的情况。
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";
回答by SachIn Harge
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;
}
回答by mathtec
The easiest is that you add the "System.ComponentModel.Browsable" attributes to your DataModel:
最简单的方法是将“System.ComponentModel.Browsable”属性添加到 DataModel:
public class TheDataModel
{
[System.ComponentModel.Browsable(false)]
public virtual int ID { get; protected set; }
public virtual string FileName { get; set; }
[System.ComponentModel.Browsable(false)]
public virtual string ColumnNotShown1 { get; set; }
[System.ComponentModel.Browsable(false)]
public virtual string ColumnNotShown2 { get; set; }
}