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

C# 如何使用自定义对象仅显示DataGridView中的某些列,c#,datagridview,C#,Datagridview,我有一个DataGridView,需要向其中添加自定义对象。考虑下面的代码: DataGridView grid = new DataGridView(); grid.DataSource = objects; 通过这段代码,我得到了一个DataGridView对象,它的所有属性都是列。就我而言,我不想显示所有这些信息;我只想显示两三列。我知道我可以设定 AutoGenerateColumns=false 但我不知道以后怎么办。 一种选择是隐藏我不感兴趣的所有列,但我认为最好是以相反的方式进行

我有一个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方法来检索底层模型对象,只是为了避免为其生成列。

您还可以在底层对象中的任何属性上使用属性[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。
把我的问题/答案放在我解释的地方。

你可以这样做

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();
要在
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";

最简单的方法是将“System.ComponentModel.Browsable”属性添加到数据模型中:

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

为列表创建新模型,如

             var today =DateTime.Today;
            DailyEnteryList = _context.Tbl_AllEntriries.Where(x => 
                x.CreatedOn.Value.Date == today.Date).
                Select(x=> new EntirysModel 
                {
                    EntiryNo=Convert.ToInt64(x.EntiryNo),
                    CustomerName=x.CustomerName,
                    Date=Convert.ToDateTime(x.Date),
                    ModelName=x.ModelName,
                }).ToList();
我的整个模型

然后在网格中添加列

[1]

:

这是用我的钱做的最好的工作 谢谢


@Overflow012这是什么意思?我需要在一行中单击时获取自定义对象。如果我这样做,我就得不到它。我说得对吗?@Overflow012说得好,我明白你的意思。是的,如果您想这样做,那么您需要使用类似于“我的编辑”中的方法。在您的示例中,
MyViewModel
是什么?在进行任何一次编辑之前,我正试图了解
对象在您的代码最顶端引用了什么。例如,它是一个数据表吗?谢谢。1+这一点很有道理,但有些OP无法理解,因此我们需要一个类似于一点点的演示文稿
:D
dataGridView1.AutoGenerateColumns=false;防止在数据绑定上显示所有列。非常感谢。你在这里的答案是最有用的,因为他们不会把
列数
。未来的程序员在设置任何列[0]时都会遇到这种类型的错误,例如空引用异常。Name/HeaderText/dataPropertyName您最好向提出请求的人解释此解决方案,这样他不仅可以复制/粘贴它,还可以通过学习从其他方面受益
 public class EntirysModel
{
    public long EntiryNo { get; set; }
    public string CustomerName { get; set; }
    public DateTime Date { get; set; }
    public string ModelName { get; set; }
}