绑定到字典的DataGridView

我有一个Dictionary包含商品和价格的商品。这些项目是唯一的,但是会在应用程序的整个生命周期内慢慢添加和更新(也就是说,我事先不知道这些项目字符串)。我想将此结构绑定到DataGridView,以便可以在Form上显示更新,例如:

Dictionary<string, double> _priceData = new Dictionary<string, double>();

BindingSource _bindingSource = new BindingSource();

dataGridView1.DataSource = _bindingSource;

_bindingSource.DataSource = _priceData;

但不能,因为Dictionary没有实现IList(或IListSourceIBindingListIBindingListView)。

有没有办法做到这一点?我需要保留一个唯一的商品列表,还需要更新现有商品的价格,因此Dictionary我认为是理想的数据结构,但是我找不到在表单上显示数据的方法。


更新:

Marc的以下建议非常有效,但是我仍然不确定执行期间如何更新DataGridView。

我有一个类级变量:

private DictionaryBindingList<string, decimal> bList;

然后在中实例化它Main()

bList = new DictionaryBindingList<string,decimal>(prices); 

dgv.DataSource = bList;

然后在程序执行过程中,是否将新条目添加到字典中:

prices.Add("foobar", 234.56M); bList.ResetBindings();

我以为那会刷新DataGridView。为什么不?

回答:

有两个问题Dictionary; 第一个是(如您所发现的)它没有实现必要的IList/

IListSource。第二个原因是,没有对项目的保证顺序(实际上,也没有索引器),这使得无法通过索引(而不是键)进行随机访问。

但是…可能有些烟和镜子是可行的。如下所示:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Windows.Forms;

static class Program

{

[STAThread]

static void Main()

{

Dictionary<string, decimal> prices =

new Dictionary<string, decimal>();

prices.Add("foo", 123.45M);

prices.Add("bar", 678.90M);

Application.EnableVisualStyles();

Form form = new Form();

DataGridView dgv = new DataGridView();

dgv.Dock = DockStyle.Fill;

form.Controls.Add(dgv);

var bl = prices.ToBindingList();

dgv.DataSource = bl;

Button btn = new Button();

btn.Dock = DockStyle.Bottom;

btn.Click += delegate

{

prices.Add(new Random().Next().ToString(), 0.1M);

bl.Reset();

};

form.Controls.Add(btn);

Application.Run(form);

}

public static DictionaryBindingList<TKey, TValue>

ToBindingList<TKey, TValue>(this IDictionary<TKey, TValue> data)

{

return new DictionaryBindingList<TKey, TValue>(data);

}

public sealed class Pair<TKey, TValue>

{

private readonly TKey key;

private readonly IDictionary<TKey, TValue> data;

public Pair(TKey key, IDictionary<TKey, TValue> data)

{

this.key = key;

this.data = data;

}

public TKey Key { get { return key; } }

public TValue Value

{

get

{

TValue value;

data.TryGetValue(key, out value);

return value;

}

set { data[key] = value; }

}

}

public class DictionaryBindingList<TKey, TValue>

: BindingList<Pair<TKey, TValue>>

{

private readonly IDictionary<TKey, TValue> data;

public DictionaryBindingList(IDictionary<TKey, TValue> data)

{

this.data = data;

Reset();

}

public void Reset()

{

bool oldRaise = RaiseListChangedEvents;

RaiseListChangedEvents = false;

try

{

Clear();

foreach (TKey key in data.Keys)

{

Add(new Pair<TKey, TValue>(key, data));

}

}

finally

{

RaiseListChangedEvents = oldRaise;

ResetBindings();

}

}

}

}

请注意,自定义扩展方法的使用完全是可选的,并且可以在C#2.0等中通过仅使用new

DictionaryBindingList<string,decimal>(prices)来删除。

以上是 绑定到字典的DataGridView 的全部内容, 来源链接: utcz.com/qa/409486.html

回到顶部