在具有对象 DataSource 的 DataGridView 中设置自动生成列的格式
Set Format of auto-generated columns in DataGridView having object DataSource
我想根据我的自定义 class 为我的 DataGridView
自动创建所有列。一切正常,但我需要格式化和对齐单元格值。
是否有一个属性可以添加到我的字段 (HeightMeter) 中,以便它可以根据需要对齐和设置格式。要在手动列创建代码中执行此操作,您将使用以下内容:
DataGridViewColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
DataGridViewColumn.DefaultCellStyle.Format = "N2";
如何在使用 AutoGenerateColumns 解决方案时指定 DefaultCellStyle 属性 - 注意我仅限于使用 .net 2 :(
这是我需要的和我得到的示例:
public partial class Form1 : Form
{
private List<Person> people = new List<Person>();
private DataGridView dataGridView1 = new DataGridView();
private DataGridView dataGridView2 = new DataGridView();
public Form1()
{
InitializeComponent();
dataGridView1.Dock = DockStyle.Top;
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
dataGridView2.Dock = DockStyle.Top;
dataGridView2.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
Controls.Add(dataGridView2);
Controls.Add(dataGridView1);
Load += new EventHandler(Form1_Load);
Text = "";
}
private void Form1_Load(object sender, EventArgs e)
{
PopulateLists();
dataGridView1.AutoGenerateColumns = true;
dataGridView1.DataSource = people;
CreateAndPopulateGrid2();
}
public void CreateAndPopulateGrid2()
{
DataGridViewColumn columnName = new DataGridViewTextBoxColumn();
columnName.HeaderText = "Name";
DataGridViewColumn columnHeight = new DataGridViewTextBoxColumn();
columnHeight.HeaderText = "Height [m]";
columnHeight.ValueType = typeof(double);
columnHeight.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
columnHeight.DefaultCellStyle.Format = "N2";
dataGridView2.Rows.Clear();
dataGridView2.Columns.Clear();
dataGridView2.Columns.Add(columnName);
dataGridView2.Columns.Add(columnHeight);
DataGridViewRow row;
foreach (Person p in people)
{
row = new DataGridViewRow();
row.CreateCells(dataGridView2);
row.Cells[0].Value = p.Name;
row.Cells[1].Value = p.HeightMeter;
dataGridView2.Rows.Add(row);
}
}
private void PopulateLists()
{
people.Clear();
people.Add(new Person("Harry", 1.7523));
people.Add(new Person("Sally", 1.658));
people.Add(new Person("Roy", 2.158));
people.Add(new Person("Pris", 1.2584));
}
}
class Person
{
[System.ComponentModel.DisplayName("Name")]
public string Name { get; set; }
[System.ComponentModel.DisplayName("Height [m]")]
public double HeightMeter { get; set; }
public Person(string name, double heightMeter)
{
Name = name;
HeightMeter = heightMeter;
}
}
使用自定义属性控制 DataGridView 列的外观
在 DataGridView
中自动生成列时,内置支持一些属性,包括 ReadOnly
、DisplayName
和 Browsable
属性。例如,如果您使用 Browsable(false)
标记 属性,它将不会作为列添加到 DataGridView
。
但是对于Format
,没有这样的内置支持。您可以创建自定义 DisplayFormat
属性并编写一些代码以在自动生成列后在 DataGridView
中使用它。
例如,假设您有这样一个 class:
using System;
using System.ComponentModel;
public class Product
{
[DisplayName("Code")]
[Description("Unique code of the product")]
public int Id { get; set; }
[DisplayName("Product Name")]
[Description("Name of the product")]
public string Name { get; set; }
[DisplayName("Unit Price")]
[Description("Unit price of the product")]
[DisplayFormat("C2")]
public double Price { get; set; }
}
因此,我们将有一个像屏幕截图一样的 DataGridView
,可以看到我们使用了 Description
属性的值作为列的工具提示文本,并且我们还使用了 DisplayFormat
以货币格式显示价格:
首先我们应该为格式创建自定义属性,DisplayFormat
:
using System;
using System.ComponentModel;
public class DisplayFormatAttribute : Attribute
{
public DisplayFormatAttribute(string format)
{
Format = format;
}
public string Format { get; set; }
}
然后加载数据并自动生成列,例如:
var list = new List<Product>() {
new Product(){ Id=1, Name="Product 1", Price= 321.1234},
new Product(){ Id=2, Name="Product 2", Price= 987.5678},
};
this.dataGridView1.DataSource = list;
然后要利用属性,您可以编写不依赖于模型类型的代码:
var type = ListBindingHelper.GetListItemType(dataGridView1.DataSource);
var properties = TypeDescriptor.GetProperties(type);
foreach (DataGridViewColumn column in dataGridView1.Columns)
{
var p = properties[column.DataPropertyName];
if (p != null)
{
var format = (DisplayFormatAttribute)p.Attributes[typeof(DisplayFormatAttribute)];
column.ToolTipText = p.Description;
column.DefaultCellStyle.Format = format == null ? null : format.Format;
}
}
你可以简单地将上面的代码封装在一个像void SetupColumn(DataGridView dgv)
这样的方法中,或者如果你有一个派生的DataGridView
,你可以创建一个DataBind(object data)
方法并在该方法中赋值data
到 DataSource
然后使用上面的代码作为方法的其余部分。
备注
我还在你的问题下的评论中看到你告诉'...每个字段有点多。' 如果出于任何原因你不喜欢属性方法,您可以像这样简单地坚持 for 循环:
foreach (DataGridViewColumn c in dataGridView1.Columns)
{
if (c.ValueType == typeof(double))
{
c.DefaultCellStyle.Format = "C2";
c.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
}
}
Windows 表单中的 DataAnnotations 属性
要了解如何在 DataGridView 和验证的 Windows 表单中使用数据注释属性,请查看这些帖子:
我想根据我的自定义 class 为我的 DataGridView
自动创建所有列。一切正常,但我需要格式化和对齐单元格值。
是否有一个属性可以添加到我的字段 (HeightMeter) 中,以便它可以根据需要对齐和设置格式。要在手动列创建代码中执行此操作,您将使用以下内容:
DataGridViewColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
DataGridViewColumn.DefaultCellStyle.Format = "N2";
如何在使用 AutoGenerateColumns 解决方案时指定 DefaultCellStyle 属性 - 注意我仅限于使用 .net 2 :(
这是我需要的和我得到的示例:
public partial class Form1 : Form
{
private List<Person> people = new List<Person>();
private DataGridView dataGridView1 = new DataGridView();
private DataGridView dataGridView2 = new DataGridView();
public Form1()
{
InitializeComponent();
dataGridView1.Dock = DockStyle.Top;
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
dataGridView2.Dock = DockStyle.Top;
dataGridView2.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
Controls.Add(dataGridView2);
Controls.Add(dataGridView1);
Load += new EventHandler(Form1_Load);
Text = "";
}
private void Form1_Load(object sender, EventArgs e)
{
PopulateLists();
dataGridView1.AutoGenerateColumns = true;
dataGridView1.DataSource = people;
CreateAndPopulateGrid2();
}
public void CreateAndPopulateGrid2()
{
DataGridViewColumn columnName = new DataGridViewTextBoxColumn();
columnName.HeaderText = "Name";
DataGridViewColumn columnHeight = new DataGridViewTextBoxColumn();
columnHeight.HeaderText = "Height [m]";
columnHeight.ValueType = typeof(double);
columnHeight.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
columnHeight.DefaultCellStyle.Format = "N2";
dataGridView2.Rows.Clear();
dataGridView2.Columns.Clear();
dataGridView2.Columns.Add(columnName);
dataGridView2.Columns.Add(columnHeight);
DataGridViewRow row;
foreach (Person p in people)
{
row = new DataGridViewRow();
row.CreateCells(dataGridView2);
row.Cells[0].Value = p.Name;
row.Cells[1].Value = p.HeightMeter;
dataGridView2.Rows.Add(row);
}
}
private void PopulateLists()
{
people.Clear();
people.Add(new Person("Harry", 1.7523));
people.Add(new Person("Sally", 1.658));
people.Add(new Person("Roy", 2.158));
people.Add(new Person("Pris", 1.2584));
}
}
class Person
{
[System.ComponentModel.DisplayName("Name")]
public string Name { get; set; }
[System.ComponentModel.DisplayName("Height [m]")]
public double HeightMeter { get; set; }
public Person(string name, double heightMeter)
{
Name = name;
HeightMeter = heightMeter;
}
}
使用自定义属性控制 DataGridView 列的外观
在 DataGridView
中自动生成列时,内置支持一些属性,包括 ReadOnly
、DisplayName
和 Browsable
属性。例如,如果您使用 Browsable(false)
标记 属性,它将不会作为列添加到 DataGridView
。
但是对于Format
,没有这样的内置支持。您可以创建自定义 DisplayFormat
属性并编写一些代码以在自动生成列后在 DataGridView
中使用它。
例如,假设您有这样一个 class:
using System;
using System.ComponentModel;
public class Product
{
[DisplayName("Code")]
[Description("Unique code of the product")]
public int Id { get; set; }
[DisplayName("Product Name")]
[Description("Name of the product")]
public string Name { get; set; }
[DisplayName("Unit Price")]
[Description("Unit price of the product")]
[DisplayFormat("C2")]
public double Price { get; set; }
}
因此,我们将有一个像屏幕截图一样的 DataGridView
,可以看到我们使用了 Description
属性的值作为列的工具提示文本,并且我们还使用了 DisplayFormat
以货币格式显示价格:
首先我们应该为格式创建自定义属性,DisplayFormat
:
using System;
using System.ComponentModel;
public class DisplayFormatAttribute : Attribute
{
public DisplayFormatAttribute(string format)
{
Format = format;
}
public string Format { get; set; }
}
然后加载数据并自动生成列,例如:
var list = new List<Product>() {
new Product(){ Id=1, Name="Product 1", Price= 321.1234},
new Product(){ Id=2, Name="Product 2", Price= 987.5678},
};
this.dataGridView1.DataSource = list;
然后要利用属性,您可以编写不依赖于模型类型的代码:
var type = ListBindingHelper.GetListItemType(dataGridView1.DataSource);
var properties = TypeDescriptor.GetProperties(type);
foreach (DataGridViewColumn column in dataGridView1.Columns)
{
var p = properties[column.DataPropertyName];
if (p != null)
{
var format = (DisplayFormatAttribute)p.Attributes[typeof(DisplayFormatAttribute)];
column.ToolTipText = p.Description;
column.DefaultCellStyle.Format = format == null ? null : format.Format;
}
}
你可以简单地将上面的代码封装在一个像void SetupColumn(DataGridView dgv)
这样的方法中,或者如果你有一个派生的DataGridView
,你可以创建一个DataBind(object data)
方法并在该方法中赋值data
到 DataSource
然后使用上面的代码作为方法的其余部分。
备注
我还在你的问题下的评论中看到你告诉'...每个字段有点多。' 如果出于任何原因你不喜欢属性方法,您可以像这样简单地坚持 for 循环:
foreach (DataGridViewColumn c in dataGridView1.Columns)
{
if (c.ValueType == typeof(double))
{
c.DefaultCellStyle.Format = "C2";
c.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
}
}
Windows 表单中的 DataAnnotations 属性
要了解如何在 DataGridView 和验证的 Windows 表单中使用数据注释属性,请查看这些帖子: