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

时间:2013-02-10 02:16:42

标签: c# datagridview

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

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

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

AutoGenerateColumns = false

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

8 个答案:

答案 0 :(得分:25)

每当我这样做时,我通常会在对象上进行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方法来检索底层模型对象的原因只是为了避免为它生成一个列。

答案 1 :(得分:10)

您也可以在底层对象的任何属性上使用Attribute [Browsable(false)],这可能是合适的。这当然会阻止列在其他地方可浏览,所以你可能会发现这是不合需要的。

答案 2 :(得分:10)

您可以将数据绑定与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。 请问我的问题/答案here,我一直向下解释。

答案 3 :(得分:5)

你可以这样做。

要首先在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

但我认为它运作良好。

答案 4 :(得分:5)

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

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

答案 5 :(得分:3)

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

答案 6 :(得分:3)

最简单的方法是将“ 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; }
}

答案 7 :(得分:0)

为列表创建新模型,如....

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

我的EntirysModel

 public class EntirysModel
{
    public long EntiryNo { get; set; }
    public string CustomerName { get; set; }
    public DateTime Date { get; set; }
    public string ModelName { get; set; }
}

然后在网格中添加列

[1]

https://i.stack.imgur.com/3dZAl.png

这是我最好的工作 谢谢!!!