数据绑定动态数据

我需要绑定到GridControl的一组“动态数据”。到目前为止,我一直在使用标准的DataTable类,该类是System.Data命名空间的一部分。这个工作很好,但是有人告诉我我不能使用它,因为它对于客户端和服务器之间的网络序列化来说太重了。

因此,我认为我可以轻松地复制DataTable类的“精简版本”,只需使用一种类型即可,List<Dictionary<string,

object>>其中List表示行的集合,每个Dictionary表示一行,其中列名和值作为KeyValuePair类型。我可以将Grid设置为具有列DataField属性,以匹配Dictionary中的键的属性(就像我为DataTable的列名所做的那样)。

但是做完之后

gridControl.DataSource = table;

gridControl.RefreshDataSource();

网格没有数据…

我想我需要实施IEnumerator-在此方面的任何帮助将不胜感激!

示例调用代码如下所示:

var table = new List<Dictionary<string,object>>();

var row = new Dictionary<string, object>

{

{"Field1", "Data1"},

{"Field2", "Data2"},

{"Field3", "Data3"}

};

table.Add(row);

gridControl1.DataSource = table;

gridControl1.RefreshDataSource();

回答:

欢迎来到System.ComponentModel的美好世界。.NET的这个黑暗角落非常强大,但非常复杂。

谨防 除非您有很多时间-

可以按照自己喜欢的任何机制简单地对其进行序列化,然后将其重新补水到DataTable每个末端,这可能会做得很好…接下来的内容并不适合胆小的人;-p

首先-数据绑定(用于表)对 列表IList/

)起作用IListSource-因此List<T>应该没问题(编辑:我误读了一些内容)。但这并不能理解您的词典实际上是列…

要使类型假装具有列,您需要使用自定义PropertyDescriptor实现。有多种方法可以执行此操作,具体取决于列定义是否始终相同(但在运行时确定,即可能由config确定),或者是否每次使用都会更改(例如每个DataTable实例如何具有不同的列)。

对于“每个实例”的定制,你需要看一下ITypedList-这兽(中实现 除了

IList)有呈现表格数据属性的好玩的事......但它并不孤单:

对于“每种类型”定制,您可以看一下TypeDescriptionProvider-这可以为类建议动态属性…

…或您可以实现ICustomTypeDescriptor-但这仅在 少数情况下使用(用于列表)(对象索引器(public object

this[int index] {get;}“)和绑定时列表中至少有一行)。(此接口非常有用绑定离散对象时-即不列出)。

实现ITypedList并提供PropertyDescriptor模型是一项艰苦的工作……因此,它只是偶尔执行。我对此相当熟悉,但我不会只是为了笑而已…


这是一个

实现(所有列都是字符串;没有通知(通过描述符),没有验证(IDataErrorInfo),没有转换(TypeConverter),没有其他列表支持(IBindingList/

IBindingListView),没有抽象(IListSource),没有其他其他元数据/属性,等等):

using System.ComponentModel;

using System.Collections.Generic;

using System;

using System.Windows.Forms;

static class Program

{

[STAThread]

static void Main()

{

Application.EnableVisualStyles();

PropertyBagList list = new PropertyBagList();

list.Columns.Add("Foo");

list.Columns.Add("Bar");

list.Add("abc", "def");

list.Add("ghi", "jkl");

list.Add("mno", "pqr");

Application.Run(new Form {

Controls = {

new DataGridView {

Dock = DockStyle.Fill,

DataSource = list

}

}

});

}

}

class PropertyBagList : List<PropertyBag>, ITypedList

{

public PropertyBag Add(params string[] args)

{

if (args == null) throw new ArgumentNullException("args");

if (args.Length != Columns.Count) throw new ArgumentException("args");

PropertyBag bag = new PropertyBag();

for (int i = 0; i < args.Length; i++)

{

bag[Columns[i]] = args[i];

}

Add(bag);

return bag;

}

public PropertyBagList() { Columns = new List<string>(); }

public List<string> Columns { get; private set; }

PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors)

{

if(listAccessors == null || listAccessors.Length == 0)

{

PropertyDescriptor[] props = new PropertyDescriptor[Columns.Count];

for(int i = 0 ; i < props.Length ; i++)

{

props[i] = new PropertyBagPropertyDescriptor(Columns[i]);

}

return new PropertyDescriptorCollection(props, true);

}

throw new NotImplementedException("Relations not implemented");

}

string ITypedList.GetListName(PropertyDescriptor[] listAccessors)

{

return "Foo";

}

}

class PropertyBagPropertyDescriptor : PropertyDescriptor

{

public PropertyBagPropertyDescriptor(string name) : base(name, null) { }

public override object GetValue(object component)

{

return ((PropertyBag)component)[Name];

}

public override void SetValue(object component, object value)

{

((PropertyBag)component)[Name] = (string)value;

}

public override void ResetValue(object component)

{

((PropertyBag)component)[Name] = null;

}

public override bool CanResetValue(object component)

{

return true;

}

public override bool ShouldSerializeValue(object component)

{

return ((PropertyBag)component)[Name] != null;

}

public override Type PropertyType

{

get { return typeof(string); }

}

public override bool IsReadOnly

{

get { return false; }

}

public override Type ComponentType

{

get { return typeof(PropertyBag); }

}

}

class PropertyBag

{

private readonly Dictionary<string, string> values

= new Dictionary<string, string>();

public string this[string key]

{

get

{

string value;

values.TryGetValue(key, out value);

return value;

}

set

{

if (value == null) values.Remove(key);

else values[key] = value;

}

}

}

以上是 数据绑定动态数据 的全部内容, 来源链接: utcz.com/qa/403357.html

回到顶部