Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 绑定到字典的DataGridView_C#_.net_Winforms_Datagridview_Dictionary - Fatal编程技术网

C# 绑定到字典的DataGridView

C# 绑定到字典的DataGridView,c#,.net,winforms,datagridview,dictionary,C#,.net,Winforms,Datagridview,Dictionary,我有一本字典,里面有商品和价格。这些项是唯一的,但在应用程序的整个生命周期中都会缓慢地添加和更新(也就是说,我事先不知道这些项的字符串)。我想将此结构绑定到DataGridView,以便在表单上显示更新,例如: Dictionary<string, double> _priceData = new Dictionary<string, double>(); BindingSource _bindingSource = new BindingSource(); dataGr

我有一本
字典
,里面有商品和价格。这些项是唯一的,但在应用程序的整个生命周期中都会缓慢地添加和更新(也就是说,我事先不知道这些项的字符串)。我想将此结构绑定到DataGridView,以便在表单上显示更新,例如:

Dictionary<string, double> _priceData = new Dictionary<string, double>();
BindingSource _bindingSource = new BindingSource();
dataGridView1.DataSource = _bindingSource;
_bindingSource.DataSource = _priceData;
然后在
Main()中实例化:


我认为这会刷新DataGridView。为什么不呢?

字典有几个问题
;第一个是(正如您所发现的),它没有实现必要的
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();
            }
        }

    }
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用System.Windows.Forms;
静态类程序
{
[状态线程]
静态void Main()
{
字典价格=
新字典();
价格。添加(“foo”,123.45米);
价格。添加(“酒吧”,678.90米);
Application.EnableVisualStyles();
表单=新表单();
DataGridView dgv=新建DataGridView();
dgv.Dock=DockStyle.Fill;
表单.控件.添加(dgv);
var bl=价格。ToBindingList();
dgv.DataSource=bl;
按钮btn=新按钮();
btn.Dock=DockStyle.Bottom;
点击+=委托
{
添加(新随机().Next().ToString(),0.1M);
bl.Reset();
};
表单.控件.添加(btn);
申请表格;
}
公共静态字典绑定列表
ToBindingList(此IDictionary数据)
{
返回新字典BindingList(数据);
}
公共密封类对
{
专用只读TKey密钥;
专用只读词典数据;
公共对(TKey、IDictionary数据)
{
this.key=key;
这个数据=数据;
}
公钥{get{return Key;}}
公共价值
{
得到
{
t价值;
数据.TryGetValue(键,输出值);
返回值;
}
设置{data[key]=value;}
}
}
公共类字典绑定列表
:BindingList
{
专用只读词典数据;
公共词典绑定列表(IDictionary数据)
{
这个数据=数据;
重置();
}
公共无效重置()
{
bool oldRaise=RaiseListChangedEvents;
RaiseListChangedEvents=false;
尝试
{
清除();
foreach(TKey-in-data.Keys)
{
添加(新对(密钥、数据));
}
}
最后
{
RaiseListChangedEvents=oldRaise;
重置绑定();
}
}
}
}
请注意,自定义扩展方法的使用完全是可选的,在C#2.0等中,只需使用
新字典BindingList(prices)
即可将其删除。

创建如下类:

class MyRow
{
    public string key;
    public double value;
    public string Key {get {return key;}}
    public string Value {get {return value;}}
}
然后列出它们:

List<MyRow> rows = new List<MyRow>();
列表行=新列表();
然后将它们插入该列表,并将其数据绑定到该列表


顺便说一句,如果你有LINQ,我认为有一种
ToArray
方法可以简化所有这些…

或者,在LINQ中,它又好又快:

var _priceDataArray = from row in _priceData select new { Item = row.Key, Price = row.Value };
然后应该可以绑定到“Item”和“Price”列

要在网格视图中将其用作数据源,只需使用
ToArray()
跟随它即可

对于
字典
,可以使用以下关键字进行绑定:

    ComboBox1.DataSource =
        new BindingSource(Pricelevel.GetPricelevels(), null); // GetPricelevels() returns Dictionary<string, string>

    ComboBox1.ValueMember = "Key";
    ComboBox1.DisplayMember = "Value";
下面是绑定
组合框的示例,但是可以将字典绑定到
DataGridView
(将列的
DataPropertyName
设置为
Key
Value

ComboBox1.DataSource=
新BindingSource(Pricelevel.getPriceLevel(),null);//getPriceLevel()返回字典
ComboBox1.ValueMember=“Key”;
ComboBox1.DisplayMember=“值”;

我想这会解决我几个月前遇到的问题

当您想要更新商品价格时,请使用字典,当您完成更新并希望在datagrid中显示时,请执行此操作。希望对你有帮助

Grd.DataSource=null;
Grd.DataSource = Dictionary.Values.ToList();

也许这是最简单的方法:

Dictionary<char, double> myList = new Dictionary<char, double>();

        dataGridView1.Columns.Add("Key", "KEY");
        dataGridView1.Columns.Add("Values", "VALUES");

        foreach (KeyValuePair<char,double> item in , myList)
        {
            dataGridView1.Rows.Add(item.Key, item.Value);
        }
Dictionary myList=newdictionary();
dataGridView1.Columns.Add(“Key”,“Key”);
dataGridView1.Columns.Add(“值”、“值”);
foreach(myList中的KeyValuePair项)
{
dataGridView1.Rows.Add(item.Key、item.Value);
}

如果使用此选项,则datagridview应可排序。

作为Marc建议的扩展,我想提出以下解决方案,该解决方案还将允许对字典进行运行时操作:

public class DictionaryBindingList<TKey, TValue> : BindingList<KeyValuePair<TKey, TValue>>
{
    public readonly IDictionary<TKey, TValue> Dictionary;
    public DictionaryBindingList()
    {
        Dictionary = new Dictionary<TKey, TValue>();
    }

    public void Add(TKey key, TValue value)
    {
        base.Add(new KeyValuePair<TKey, TValue>(key, value));
    }

    public void Remove(TKey key)
    {
        var item = this.First(x => x.Key.Equals(key));
        base.Remove(item);
    }

    protected override void InsertItem(int index, KeyValuePair<TKey, TValue> item)
    {
        Dictionary.Add(item.Key, item.Value);
        base.InsertItem(index, item);
    }

    protected override void RemoveItem(int index)
    {
        Dictionary.Remove(this[index].Key);
        base.RemoveItem(index);
    }

    public int IndexOf(TKey key)
    {
        var item = this.FirstOrDefault(x => x.Key.Equals(key));
        return item.Equals(null) ? -1 : base.IndexOf(item);
    }
}
公共类字典BindingList:BindingList
{
公共只读词典;
公共字典绑定列表()
{
字典=新字典();
}
公共无效添加(TKey键,TValue值)
{
添加(新的KeyValuePair(key,value));
}
公共无效删除(TKey)
{
var item=this.First(x=>x.Key.Equals(Key));
底座。移除(项目);
}
受保护的重写void插入项(int索引,KeyValuePair项)
{
Dictionary.Add(item.Key、item.Value);
基本插入项(索引,项目);
}
受保护的覆盖void removietem(int索引)
{
Dictionary.Remove(此[index].Key);
基本删除项(索引);
}
public int IndexOf(TKey)
{
var item=this.FirstOrDefault(x=>x.Key.Equals(Key));
返回项.Equals(null)?-1:base.IndexOf
    ComboBox1.DataSource =
        new BindingSource(Pricelevel.GetPricelevels(), null); // GetPricelevels() returns Dictionary<string, string>

    ComboBox1.ValueMember = "Key";
    ComboBox1.DisplayMember = "Value";
Grd.DataSource=null;
Grd.DataSource = Dictionary.Values.ToList();
Dictionary<char, double> myList = new Dictionary<char, double>();

        dataGridView1.Columns.Add("Key", "KEY");
        dataGridView1.Columns.Add("Values", "VALUES");

        foreach (KeyValuePair<char,double> item in , myList)
        {
            dataGridView1.Rows.Add(item.Key, item.Value);
        }
public class DictionaryBindingList<TKey, TValue> : BindingList<KeyValuePair<TKey, TValue>>
{
    public readonly IDictionary<TKey, TValue> Dictionary;
    public DictionaryBindingList()
    {
        Dictionary = new Dictionary<TKey, TValue>();
    }

    public void Add(TKey key, TValue value)
    {
        base.Add(new KeyValuePair<TKey, TValue>(key, value));
    }

    public void Remove(TKey key)
    {
        var item = this.First(x => x.Key.Equals(key));
        base.Remove(item);
    }

    protected override void InsertItem(int index, KeyValuePair<TKey, TValue> item)
    {
        Dictionary.Add(item.Key, item.Value);
        base.InsertItem(index, item);
    }

    protected override void RemoveItem(int index)
    {
        Dictionary.Remove(this[index].Key);
        base.RemoveItem(index);
    }

    public int IndexOf(TKey key)
    {
        var item = this.FirstOrDefault(x => x.Key.Equals(key));
        return item.Equals(null) ? -1 : base.IndexOf(item);
    }
}
    public void Add(TKey key, TValue value)
    {
        if (Dictionary.ContainsKey(key))
        {
            int position = IndexOf(key);
            Dictionary.Remove(key);
            Remove(key);
            InsertItem(position, new KeyValuePair<TKey, TValue>(key, value));
            return;
        }
        base.Add(new KeyValuePair<TKey, TValue>(key, value));
    }