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;
}