在具有对象DataSource的DataGridView中设置自动生成的列的格式 [英] Set Format of auto-generated columns in DataGridView having object DataSource

查看:91
本文介绍了在具有对象DataSource的DataGridView中设置自动生成的列的格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想根据我的自定义类为 DataGridView 自动创建所有列。一切正常,但我需要格式化和对齐单元格值。

I would like to auto create all the columns for my DataGridView based on my custom class. Every thing works like it should, but what I need is to format and align the cell values.

所以有一个可以添加到字段中的属性(高度表)以便可以根据需要对齐和格式化。为此,请在手动创建代码列中使用以下代码:

So is there an attribute that I can add to my field (HeightMeter) so that it can align and format as required. To do this in a manual column create code, You will use the following:

DataGridViewColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
DataGridViewColumn.DefaultCellStyle.Format = "N2";

使用AutoGenerateColumns解决方案时如何指定DefaultCellStyle属性-注意,我仅限于使用.net 2 :(

How to I specify the DefaultCellStyle properties when using the AutoGenerateColumns solution - Note I am limited to using .net 2 :(

以下是我需要和得到的东西的示例:

Here is a sample of what I need and what I get:

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 中。

Using custom attributes to control appearance of DataGridView columns

When auto-generating columns in DataGridView, there is built-in support for a few attributes including ReadOnly, DisplayName and Browsable attribute. For example, if you mark a property using Browsable(false) it will not be added as a column to DataGridView.

但是对于 Format ,没有这种内置支持。您可以创建一个自定义的 DisplayFormat 属性,并在自动生成列之后编写一些代码以在 DataGridView 中使用它。

But for Format, there is no such built-in support. You can create a custom DisplayFormat attribute and write some code to use it in DataGridView after auto generating columns.

例如,假设您有一个这样的类:

For example, let's say you have a class like this:

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 以货币格式显示价格:

And as a result, we are going to have a DataGridView like the screenshot, which can see we used the value of Description attribute as tooltip text for columns and also we used DisplayFormat to show the price in currency format:

首先,我们应该为 DisplayFormat 格式创建自定义属性:

First we should create the custom attribute for format, DisplayFormat:

using System;
using System.ComponentModel;
public class DisplayFormatAttribute : Attribute
{
    public DisplayFormatAttribute(string format)
    {
        Format = format;
    }
    public string Format { get; set; }
}

然后加载数据并自动生成列,例如:

Then load data and auto generate columns, for example:

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;

然后,利用属性,您可以编写不依赖于模型类型的代码:

Then to take advantage of attributes, you can write such code which is not dependent to the model type:

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 (对象数据)方法,在该方法中,将 data 分配给 DataSource ,然后使用上面的代码作为方法的其余部分。

You can simply encapsulate above code in a method like void SetupColumn(DataGridView dgv) or if you have a derived DataGridView, you can create a DataBind(object data) method and in the method, assign data to DataSource and then use above code as rest of body of the method.

注意

在您的问题下的注释中读到您已经告诉' ...因为每个字段都太多了。'。如果出于某种原因您不喜欢属性方法,则可以坚持使用for循环是这样的:

I also read in the comments under your question that you have told '...for each field is a bit much.' If for any reason you don't like the attribute approach, you can simply stick to a for loop like this:

foreach (DataGridViewColumn c in dataGridView1.Columns)
{
    if (c.ValueType == typeof(double))
    {
        c.DefaultCellStyle.Format = "C2";
        c.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
    }
}



Windows窗体中的DataAnnotations属性



要查看如何在Windows窗体中将数据批注属性用于DataGridView和验证,请看一下这些帖子:

DataAnnotations attributes for in Windows Forms

To see how can you use data annotations attribute in Windows Forms for DataGridView and also for Validation, take a look at these posts:

  • DataAnnotations attributes for DataGridView in Windows Forms
  • DataAnnotations Validation attributes for Windows Forms

这篇关于在具有对象DataSource的DataGridView中设置自动生成的列的格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆