Как показать только определенные столбцы в DataGridView с настраиваемыми объектами
У меня есть DataGridView, и мне нужно добавить к нему пользовательские объекты. Рассмотрим следующий код:
DataGridView grid = new DataGridView();
grid.DataSource = objects;
С помощью этого кода я получаю объект DataGridView со всеми свойствами в виде столбцов. В моем случае я не хочу показывать всю эту информацию; Я хочу показать только два или три столбца. Я знаю, что могу установить
AutoGenerateColumns = false
.
Но я не знаю, как действовать дальше.
Один из вариантов - скрыть все столбцы, которые меня не интересуют, но я думаю, что было бы лучше сделать это наоборот. Как я могу это сделать?
Ответы
Ответ 1
Всякий раз, когда я это делаю, я обычно делаю grid.DataSource
результат проекции LINQ на объекты.
Так что-то вроде этого:
grid.DataSource = objects.Select(o => new
{ Column1 = o.SomeValue, Column2 = o.SomeOtherValue }).ToList();
Самое приятное, что вы можете установить AutoGenerateColumns
в значение true, которое будет генерировать столбцы на основе свойств проецируемых объектов.
Edit:
Единственным недостатком этого подхода является то, что, проектируя все в анонимный объект, вы можете иметь проблемы в ситуациях, когда вам нужно, например, получить доступ к определенному объекту в событии клика.
В этом случае вам может быть лучше определить явную модель представления и проецировать ваши объекты на них. Например.
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 для получения базового объекта модели, - это просто избежать создания столбца для него.
Ответ 2
Вы также можете использовать Attribute [Browsable (false)] для любого свойства в базовых объектах, что может быть уместно. Это, конечно же, приведет к тому, что столбец не будет доступен для просмотра в другом месте, поэтому вы можете обнаружить, что это нежелательно.
Ответ 3
Вы можете использовать привязки данных с помощью AutoGenerateColumns = false
и используя DataPropertyName, как это
grid.Columns["Column_name_1"].DataPropertyName = "public_property_1";
grid.Columns["Column_name_2"].DataPropertyName = "public_property_2";
Таким образом, только привязанные столбцы будут показаны в представлении datagridview, и вы можете создать столбцы в редакторе, если хотите. Открытые свойства могут быть любыми публичными атрибутами внутри вашего объекта.
Если вы редактируете свои данные из datagridview, вы должны использовать NotifyPropertyChanged в методах набора.
Se my question/answer здесь, где я объясняю это до конца.
Ответ 4
Вы можете сделать что-то вроде этого.
Чтобы отображать только столбцы цветности в 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
Но я думаю, что он отлично работает.
Ответ 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";
Ответ 6
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;
}