[英]DataGridView with run-time columns
I'm using C#, Windows Forms, .NET 3.5 SP1 我正在使用C#,Windows Forms,.NET 3.5 SP1
I have a DataGridView with a lot of columns that I don't know about until run-time (ie I don't know I need a Foo column until run-time). 我有一个DataGridView,其中包含很多直到运行时才知道的列(即,我不知道直到运行时才需要Foo列)。 To get data into and out of the cells, I'm thinking about the following architecture.
为了使数据进出单元,我正在考虑以下架构。
Am I on the right track, or am I missing something easier? 我是在正确的轨道上,还是我缺少一些轻松的事情?
public interface ICustomColumn
{
object Format (DataGridView dgv, DataGridViewCellFormattingEventArgs e);
void Validate (DataGridView dgv, DataGridViewCellValidatingEventArgs e);
}
public class CustomDataGridView : DataGridView
{
protected override void OnCellFormatting (DataGridViewCellFormattingEventArgs e)
{
ICustomColumn col = Columns [e.ColumnIndex].Tag as ICustomColumn;
if ( col != null )
e.Value = col.Format (this, e);
base.OnCellFormatting (e);
}
protected override void OnCellValidating (DataGridViewCellValidatingEventArgs e)
{
ICustomColumn col = Columns [e.ColumnIndex].Tag as ICustomColumn;
if ( col != null )
col.Validate (this, e);
base.OnCellValidating (e);
}
}
class FooColumn : ICustomColumn
{
public FooColumn (Dictionary <RowData, Foo> fooDictionary)
{ this.FooDictionary = fooDictionary; }
// Foo has a meaningful conversion to the column type (e.g. ToString () for a text column
protected object Format (DGV dgv, DGVCFEA e)
{ return FooDictionary [(RowData) dgv.Rows[e.RowIndex].DataBoundItem]; }
// Foo has a meaningful way to interpret e.FormattedValue
void Validate (DGV dgv, DGVCVEA e)
{ FooDictionary [(RowData) dgv.Rows[e.RowIndex].DataBoundItem].Validate (e.FormattedValue); }
}
void CreateFooColumn (DataGridView dgv)
{
dgv.Columns.Add (new DataGridViewTextBoxColumn () { Tag = new FooColumn (fooDictionary) });
}
Another approach would be to use reflection. 另一种方法是使用反射。
To set up the DataGridView: 设置DataGridView:
private void SetUpDataGridView()
{
// Create the columns based on the data in the album info - get by reflection
var ai = new AlbumInfo();
Type t = ai.GetType();
dataTable.TableName = t.Name;
foreach (PropertyInfo p in t.GetProperties())
{
var columnSpec = new DataColumn();
// If nullable get the underlying type
Type propertyType = p.PropertyType;
if (IsNullableType(propertyType))
{
var nc = new NullableConverter(propertyType);
propertyType = nc.UnderlyingType;
}
columnSpec.DataType = propertyType;
columnSpec.ColumnName = p.Name;
dataTable.Columns.Add(columnSpec);
}
}
The helper method: 辅助方法:
private bool IsNullableType(Type theType)
{
return (theType.IsGenericType &&
theType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)));
}
To populate the DataGridView: 要填充DataGridView:
private void AddToGrid(AlbumInfo info)
{
// Add album info to table - add by reflection
Type t = info.GetType();
var row = new object[t.GetProperties().Length];
int index = 0;
foreach (PropertyInfo p in t.GetProperties())
{
row[index++] = p.GetValue(info, null);
}
dataTable.Rows.Add(row);
dataGridView.ClearSelection();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.