class 的 IDictionary 显示在 table c# 中
IDictionary of class displayed in a table c#
我有一个 IDictionary
,其中包含我的 class 的不断变化的列表,我想在 winforms UI 中显示该集合,可能使用 DataGridView
或其他控制。我计划使用每 1 到 2 秒刷新一次 table 的计时器和一个暂停按钮。单击任何给定行时,我需要能够从字典中获取 class 或 return 作为 IDictionary
.
中的键的第一个字段
所以我这样创建 IDictionary
:
public static IDictionary<string, AClass> aList = new Dictionary<string, AClass>();
AClass
是一个简单的字符串集合:
public class AClass
{
public string data1{ get; set; }
public string data2{ get; set; }
}
我将 AClass
添加到 IDictionary
因此:
if (!MainForm.aircraftList.ContainsKey(strMyData))
{
MainForm.aList[strMyData] = new AClass{ data1= strMyData};
}
如何使用 AClass
中的所有列创建 table,这些列大约为 12,而 IDictionary
aList 中的行有一个在 100 左右徘徊的可变数字。
由于您使用的是 IDictionary,因此默认绑定机制将无法检索单个条目或 class AClass 上的属性。您可以创建自定义 BindingSource 来处理这些任务。
自定义 BingSource 的主要职责是为 AClass 类型提供一组 ProperyDescriptors。这些是使用 TypeDescriptor.GetProperties Method 检索的。 BindingSource 还需要通过索引访问底层的 DataSource 项;这是在 BindingSource 的索引器中处理的。
要使用此 BindingSource,请创建它的一个实例并传递您的 IDictionary 实例,然后将此 BindingSource 分配给 DataGridView 的数据源 属性。
internal class myBindingSource : BindingSource
{
private IDictionary<string, AClass> source;
private System.ComponentModel.PropertyDescriptorCollection props;
public myBindingSource(IDictionary<string, AClass> source)
{
this.source = source;
props = System.ComponentModel.TypeDescriptor.GetProperties(typeof(AClass));
this.DataSource = source;
}
public override System.ComponentModel.PropertyDescriptorCollection GetItemProperties(System.ComponentModel.PropertyDescriptor[] listAccessors)
{
return props;
}
public override object this[int index]
{
get {return this.source.Values.ElementAtOrDefault(index);}
set {}
}
public override bool AllowNew
{
get { return false; }
set{}
}
public override bool AllowEdit
{
get { return false; }
}
public override bool AllowRemove
{
get {return false;}
}
public override int Count
{
get {return ((this.source == null) ? -1 : this.source.Count);}
}
}
编辑:我在代码中添加了对计数 属性 的覆盖,以允许 BindingSource.ResetBindings Method 在调用时正常工作以强制绑定控件为 re-read 值来自绑定源。我还更新了索引器代码。
如果您在将自定义 BindingSource 的基础数据源指定为 DataGridView 的数据源后对其进行修改,则需要调用 BindingSource.ResetBindings 方法以使这些更改反映在网格中。
例如:
private IDictionary<string, AClass> aList;
private myBindingSource bs;
public Form1()
{
InitializeComponent();
aList = new Dictionary<string, AClass>();
bs = new myBindingSource(aList);
dgv.DataSource = bs;
aList.Add("1", new AClass());
aList.Add("2", new AClass { data1 = "AA", data2 = "BB" });
bs.ResetBindings(false);
}
为了可能帮助您入门,下面是使用 DataGridView
显示数据的代码,使用 DataTable
;一个 List<AClass>
个对象,并且还使用了一个 Dictionary<string, AClass>
。正如我所说的使用字典,您必须执行一些额外的步骤才能从字典中获取 AClass
Value
。这些额外的步骤表明,如果 class 中有多个变量,则字典不一定是用作 DataSource
的最佳数据结构。
下面的代码使用了一个 DataGridView
和四 (4) 个按钮。有一些按钮可以使用 DataTable
将数据显示到 DataGridView
;一个 List<AClass>
(添加了一个键),一个 Dictionary<string, AClass>
最后一个按钮来清除 DataGridView
希望这对您有所帮助。
public Dictionary<string, AClass> DGVDictionary;
public DataTable DGVTable;
public List<AClass> DGVList;
public Form1() {
InitializeComponent();
}
private Dictionary<string, AClass> GetDictionary() {
Dictionary<string, AClass> dictionary = new Dictionary<string, AClass>();
for (int key = 0; key < 15; key++) {
AClass ac = new AClass();
ac.data1 = "data1" + key;
ac.data2 = "data2" + key;
dictionary.Add(key.ToString(), ac);
}
return dictionary;
}
private void CreateTable() {
DGVTable = new DataTable();
DGVTable.Columns.Add("key", typeof(int));
DGVTable.Columns.Add("data1", typeof(string));
DGVTable.Columns.Add("data2", typeof(string));
}
private void FillDataTable() {
for (int key = 0; key < 15; key++) {
AClass ac = new AClass();
ac.data1 = "data1" + key;
ac.data2 = "data2" + key;
DGVTable.Rows.Add(key, ac.data1, ac.data2);
}
}
private List<AClass> FillList() {
List<AClass> list = new List<AClass>();
for (int key = 0; key < 15; key++) {
AClass ac = new AClass();
ac.key = key;
ac.data1 = "data1" + key;
ac.data2 = "data2" + key;
list.Add(ac);
}
return list;
}
private void buttonDataTable_Click(object sender, EventArgs e) {
CreateTable();
FillDataTable();
dataGridView1.DataSource = DGVTable;
MessageBox.Show("DGV with a DataTable");
}
private void buttonList_Click(object sender, EventArgs e) {
DGVList = FillList();
dataGridView1.DataSource = DGVList;
MessageBox.Show("DGV with a List<AClass>");
}
private void buttonDictionary_Click(object sender, EventArgs e) {
DGVDictionary = GetDictionary();
dataGridView1.DataSource = DGVDictionary.ToList();
MessageBox.Show("DGV with a Dictionat<string, AClass>");
}
private void buttonClear_Click(object sender, EventArgs e) {
dataGridView1.DataSource = null;
}
我有一个 IDictionary
,其中包含我的 class 的不断变化的列表,我想在 winforms UI 中显示该集合,可能使用 DataGridView
或其他控制。我计划使用每 1 到 2 秒刷新一次 table 的计时器和一个暂停按钮。单击任何给定行时,我需要能够从字典中获取 class 或 return 作为 IDictionary
.
所以我这样创建 IDictionary
:
public static IDictionary<string, AClass> aList = new Dictionary<string, AClass>();
AClass
是一个简单的字符串集合:
public class AClass
{
public string data1{ get; set; }
public string data2{ get; set; }
}
我将 AClass
添加到 IDictionary
因此:
if (!MainForm.aircraftList.ContainsKey(strMyData))
{
MainForm.aList[strMyData] = new AClass{ data1= strMyData};
}
如何使用 AClass
中的所有列创建 table,这些列大约为 12,而 IDictionary
aList 中的行有一个在 100 左右徘徊的可变数字。
由于您使用的是 IDictionary,因此默认绑定机制将无法检索单个条目或 class AClass 上的属性。您可以创建自定义 BindingSource 来处理这些任务。
自定义 BingSource 的主要职责是为 AClass 类型提供一组 ProperyDescriptors。这些是使用 TypeDescriptor.GetProperties Method 检索的。 BindingSource 还需要通过索引访问底层的 DataSource 项;这是在 BindingSource 的索引器中处理的。
要使用此 BindingSource,请创建它的一个实例并传递您的 IDictionary 实例,然后将此 BindingSource 分配给 DataGridView 的数据源 属性。
internal class myBindingSource : BindingSource
{
private IDictionary<string, AClass> source;
private System.ComponentModel.PropertyDescriptorCollection props;
public myBindingSource(IDictionary<string, AClass> source)
{
this.source = source;
props = System.ComponentModel.TypeDescriptor.GetProperties(typeof(AClass));
this.DataSource = source;
}
public override System.ComponentModel.PropertyDescriptorCollection GetItemProperties(System.ComponentModel.PropertyDescriptor[] listAccessors)
{
return props;
}
public override object this[int index]
{
get {return this.source.Values.ElementAtOrDefault(index);}
set {}
}
public override bool AllowNew
{
get { return false; }
set{}
}
public override bool AllowEdit
{
get { return false; }
}
public override bool AllowRemove
{
get {return false;}
}
public override int Count
{
get {return ((this.source == null) ? -1 : this.source.Count);}
}
}
编辑:我在代码中添加了对计数 属性 的覆盖,以允许 BindingSource.ResetBindings Method 在调用时正常工作以强制绑定控件为 re-read 值来自绑定源。我还更新了索引器代码。
如果您在将自定义 BindingSource 的基础数据源指定为 DataGridView 的数据源后对其进行修改,则需要调用 BindingSource.ResetBindings 方法以使这些更改反映在网格中。
例如:
private IDictionary<string, AClass> aList;
private myBindingSource bs;
public Form1()
{
InitializeComponent();
aList = new Dictionary<string, AClass>();
bs = new myBindingSource(aList);
dgv.DataSource = bs;
aList.Add("1", new AClass());
aList.Add("2", new AClass { data1 = "AA", data2 = "BB" });
bs.ResetBindings(false);
}
为了可能帮助您入门,下面是使用 DataGridView
显示数据的代码,使用 DataTable
;一个 List<AClass>
个对象,并且还使用了一个 Dictionary<string, AClass>
。正如我所说的使用字典,您必须执行一些额外的步骤才能从字典中获取 AClass
Value
。这些额外的步骤表明,如果 class 中有多个变量,则字典不一定是用作 DataSource
的最佳数据结构。
下面的代码使用了一个 DataGridView
和四 (4) 个按钮。有一些按钮可以使用 DataTable
将数据显示到 DataGridView
;一个 List<AClass>
(添加了一个键),一个 Dictionary<string, AClass>
最后一个按钮来清除 DataGridView
希望这对您有所帮助。
public Dictionary<string, AClass> DGVDictionary;
public DataTable DGVTable;
public List<AClass> DGVList;
public Form1() {
InitializeComponent();
}
private Dictionary<string, AClass> GetDictionary() {
Dictionary<string, AClass> dictionary = new Dictionary<string, AClass>();
for (int key = 0; key < 15; key++) {
AClass ac = new AClass();
ac.data1 = "data1" + key;
ac.data2 = "data2" + key;
dictionary.Add(key.ToString(), ac);
}
return dictionary;
}
private void CreateTable() {
DGVTable = new DataTable();
DGVTable.Columns.Add("key", typeof(int));
DGVTable.Columns.Add("data1", typeof(string));
DGVTable.Columns.Add("data2", typeof(string));
}
private void FillDataTable() {
for (int key = 0; key < 15; key++) {
AClass ac = new AClass();
ac.data1 = "data1" + key;
ac.data2 = "data2" + key;
DGVTable.Rows.Add(key, ac.data1, ac.data2);
}
}
private List<AClass> FillList() {
List<AClass> list = new List<AClass>();
for (int key = 0; key < 15; key++) {
AClass ac = new AClass();
ac.key = key;
ac.data1 = "data1" + key;
ac.data2 = "data2" + key;
list.Add(ac);
}
return list;
}
private void buttonDataTable_Click(object sender, EventArgs e) {
CreateTable();
FillDataTable();
dataGridView1.DataSource = DGVTable;
MessageBox.Show("DGV with a DataTable");
}
private void buttonList_Click(object sender, EventArgs e) {
DGVList = FillList();
dataGridView1.DataSource = DGVList;
MessageBox.Show("DGV with a List<AClass>");
}
private void buttonDictionary_Click(object sender, EventArgs e) {
DGVDictionary = GetDictionary();
dataGridView1.DataSource = DGVDictionary.ToList();
MessageBox.Show("DGV with a Dictionat<string, AClass>");
}
private void buttonClear_Click(object sender, EventArgs e) {
dataGridView1.DataSource = null;
}