Bri*_*ino 9 .net c# winforms data-annotations
我想在 Windows 窗体应用程序 (WinForms) 中的类和实体上使用数据注释。我使用 windows DataGridViews 和 Infragistics UltraGrids。我之前已经成功使用该[DisplayName("Name to Display")]属性在 DataGridView/UltraGrid 上设置列标题文本。
这是非常有益的,因为我可能有几个网格显示这个类,而不是配置每个网格来显示适当的标题文本,我可以简单地设置一个数据注释。
我还想使用以下数据注释:
例子
给定以下带注释的数据类:
public class Item
{
//Specifies that the column should not be displayed
[Display(AutoGenerateField = false)]
public int ItemID { get; set; }
//Specifies that the column should be the 1st column in the datagridview
[Display(Order = 1)]
public int Name { get; set; }
//Specifies that the column should be the 3rd column in the datagridview
//Specifies that the column header text should display "Cost" instead of "Price"
[Display(Order = 3, Name="Cost")]
//Specifies that the column should be rendered using the default local currency format string
[DataType(DataType.Currency)]
public int Price { get; set; }
//Specifies that the column should be the 4th column in the datagridview
[Display(Order = 4)]
//specifies that the column should be rendered using the datetime format string "M/d/yy h:mm tt"
[DisplayFormat(DataFormatString = "{0:M/d/yy h:mm tt")]
public DateTime ExpirationDate { get; set; }
//Specifies that the column should be the 2nd column in the datagridview
[Display(Order = 2)]
public ItemCategory Category { get; set; }
}
//Specifies that the Name column should be displayed, if referenced in a containing object
[DisplayColumn("Name")]
public class ItemCategory
{
public int CategoryID { get; set; }
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我希望 DataGridView 呈现如下:
+-------+---------------+--------+-----------------+
| Name | Category | Cost | ExpirationDate |
+-------+---------------+--------+-----------------+
| Item1 | Category1Name | $30.45 | 7/23/17 5:22 PM |
+-------+---------------+--------+-----------------+
| Item2 | Category1Name | $45.05 | 8/24/17 6:22 PM |
+-------+---------------+--------+-----------------+
| Item3 | Category2Name | $35.50 | 9/25/17 7:22 PM |
+-------+---------------+--------+-----------------+
Run Code Online (Sandbox Code Playgroud)
然而在 .Net 4.5.2 WinForms 中的 DataGridViews 实践中,数据网格实际上显示如下:
+----+-------+-------+----------------+--------------------+
| ID | Name | Price | ExpirationDate | Category |
+----+-------+-------+----------------+--------------------+
| 1 | Item1 | 30.45 | 7/23/17 | Namespace.Category |
+----+-------+-------+----------------+--------------------+
| 2 | Item2 | 45.05 | 8/24/17 | Namespace.Category |
+----+-------+-------+----------------+--------------------+
| 3 | Item3 | 35.50 | 9/25/17 | Namespace.Category |
+----+-------+-------+----------------+--------------------+
Run Code Online (Sandbox Code Playgroud)
文档
该文档声明它在 ASP.NET 和 ASP.NET MVC 中受支持。
System.ComponentModel.DataAnnotations 命名空间
System.ComponentModel.DataAnnotations 命名空间提供用于定义 ASP.NET MVC 和 ASP.NET 数据控件的元数据的属性类。
问题
似乎在 windows 窗体环境中没有采用/支持这些类。这是真的?
有没有一种简单的方法来实现对 WinForms 中数据注释的支持?
是否有一种简单的方法来注释可用于格式化 DataGridView 和/或 UltraGrid 的显示的类/实体?
Windows 窗体中没有对数据批注的内置支持,但是知道属性如何工作以及 Windows 窗体如何工作,我们可以在 Windows 窗体中使用它们。
在这篇文章中,我将展示一个扩展方法,DataGridView该方法根据数据注释属性绑定IList<T>到DataGridView和自动生成列,因此您可以DataGridView通过调用获得以下内容dataGridView1.Bind(list);:
查看以下来自数据注释属性的项目:
还有更多的东西你可以使用属性。
虽然模型是这样的:
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
[TypeDescriptionProvider(typeof(MetadataTypeTypeDescriptionProvider))]
public class Person
{
[Display(Name = "Id")]
[Browsable(false)]
public int? Id { get; set; }
[Display(Name = "First Name", Description = "First name.", Order = 1)]
public string FirstName { get; set; }
[Display(Name = "Last Name", Description = "Last name", Order = 2)]
public string LastName { get; set; }
[Display(Name = "Birth Date", Description = "Date of birth.", Order = 4)]
[DisplayFormat(DataFormatString = "yyyy-MM-dd")]
public DateTime BirthDate { get; set; }
[Display(Name = "Homepage", Description = "Url of homepage.", Order = 5)]
public string Url { get; set; }
[Display(Name = "Member", Description = "Is member?", Order = 3)]
public bool IsMember { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
Bind<T> 扩展方法
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Windows.Forms;
public static class DataGridViewExtensions
{
public static void Bind<T>(this DataGridView grid, IList<T> data,
bool autoGenerateColumns = true)
{
if (autoGenerateColumns)
{
var properties = TypeDescriptor.GetProperties(typeof(T));
var metedata = properties.Cast<PropertyDescriptor>().Select(p => new
{
Name = p.Name,
HeaderText = p.Attributes.OfType<DisplayAttribute>()
.FirstOrDefault()?.Name ?? p.DisplayName,
ToolTipText = p.Attributes.OfType<DisplayAttribute>()
.FirstOrDefault()?.GetDescription() ?? p.Description,
Order = p.Attributes.OfType<DisplayAttribute>()
.FirstOrDefault()?.GetOrder() ?? int.MaxValue,
Visible = p.IsBrowsable,
ReadOnly = p.IsReadOnly,
Format = p.Attributes.OfType<DisplayFormatAttribute>()
.FirstOrDefault()?.DataFormatString,
Type = p.PropertyType
});
var columns = metedata.OrderBy(m => m.Order).Select(m =>
{
DataGridViewColumn c;
if (m.Type == typeof(bool)) {
c = new DataGridViewCheckBoxColumn(false); }
else if (m.Type == typeof(bool?)) {
c = new DataGridViewCheckBoxColumn(true); }
else { c = new DataGridViewTextBoxColumn(); }
c.DataPropertyName = m.Name;
c.Name = m.Name;
c.HeaderText = m.HeaderText;
c.ToolTipText = m.ToolTipText;
c.DefaultCellStyle.Format = m.Format;
c.ReadOnly = m.ReadOnly;
c.Visible = m.Visible;
return c;
});
grid.Columns.Clear();
grid.Columns.AddRange(columns.ToArray());
}
grid.DataSource = data;
}
}
Run Code Online (Sandbox Code Playgroud)
同样为了支持数据注释验证,您可以IDataErrorInfo使用Validator类来实现接口,就像我在Windows Forms 的 DataAnnotations Validation 属性中所做的那样。
笔记
为了增强答案,您可能需要创建一个关心元数据属性的类型描述符,然后用该类型描述符装饰模型。您可以从使用AssociatedMetadataTypeTypeDescriptor, MetadataPropertyDescriptorWrapper,的代码开始AssociatedMetadataTypeTypeDescriptionProvider。
您也可以创建一个 Metadata 类并应用某些属性的效果,如Url或DataType对元数据。查看这篇文章会给你一些想法:将多个属性组合到一个属性 - 合并属性。
Infragistics UltraGrid 和 Windows DataGridView 都不支持这种方式的数据注释。从 15.1 开始,DevExpress 在其数据布局控件中具有一些有限的 WinForms 数据注释支持https://community.devexpress.com/blogs/thinking/archive/2015/06/08/winforms-data-layout-control-data-annotation-属性.aspx。
我找到了这个链接,其中有人通过查看元数据询问有关如何抑制 Infragistics Grid 中的列的类似问题:http : //www.infragistics.com/community/forums/t/91864.aspx
| 归档时间: |
|
| 查看次数: |
3445 次 |
| 最近记录: |