在运行时将字典列表绑定到WPF DataGrid [英] Binding of List of Dictionary to WPF DataGrid at runtime

查看:193
本文介绍了在运行时将字典列表绑定到WPF DataGrid的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我正在使用WPF和MongoDB进行一项任务.我需要在运行时从字典列表"< string,string>生成WPF DataGrid(其他任何控件都可以,如果可以的话).这是简单的集合Dictionary,其中每个Dictionary具有不同的密钥对集.

到目前为止,我已经能够在运行时从Dictionary< string,string>生成列.具有最高的列数.生成所有列之后,任务是将数据放入DataGrid并显示.

字典列表< string,string>当我尝试使用DataContext和DataGrid的ItemsSource时,每个字典中包含不同的列集,但它会生成空的网格.

请提供您的想法

Hello, I am working on one assignment using WPF and MongoDB. I need to generate WPF DataGrid(any other control will be fine if it works) at runtime from List of Dictionary<string,string>. This is simple collection Dictionary where each Dictionary has different set of keypairs.

So far i am able to generate columns at runtime from Dictionary<string,string> having highest number of columns. After generating all columns, task is to put data into DataGrid and display.

List of Dictionary<string,string> contains different set of columns in each dictionary when i tried using DataContext and ItemsSource of DataGrid but it generates empty gird.

Please provide your thoughts

推荐答案

你好
我首先选择ObservableCollection而不是List.
这是因为该列表继承了ICollectionChanged接口,因此当绑定到数据网格上的ItemSource属性的集合时,集合中的更改将出现在UI中.

其次,我不会使用字典来保存数据.我将创建一个具有所有键"或列"属性的类,并为其创建ObservableCollection.

完成所有这些操作后,我将使用MVVM模型(我个人选择),但有很多选择.我将在XAML中使用ItemSource到拥有我的值的ObservableCollection的模型中的属性的Binding.我认为,这是解决问题的快速简便的方法.

希望对您有所帮助!
Hello
I would first of all choose the ObservableCollection instead of the List.
That is because that list inherits the ICollectionChanged interface so that changes in the collection will appear in the UI when binding to the collection form the ItemSource property on the datagrid.

Second, I would not use a Dictionary to hold the data. I would create a class with properties for all the "keys" or "columns", that I create the ObservableCollection of.

When all this is done, I would use the MVVM model (my personal choice) but there are many alternatives. And I would use Binding in the XAML from the ItemSource to a property in the model holding the ObservableCollection of my values. That is a quick and easy way of solving the problem, I think.

Hope it helps!


很明显
您可能需要将List<Dictionary<string,string>>替换为更多WPF方便的集合ObservableCollection<IList<KeyValueHolder>> Items,
其中KeyValueHolder是简单实体,请参见:

Well obviously
You might need to replace List<Dictionary<string,string>> to more WPF convenient collection ObservableCollection<IList<KeyValueHolder>> Items ,
where KeyValueHolder is siple entity , see:

public class KeyValueHolder
{
 public string Key {get;set;}
 public string Value {get;set;}
} 

.

但是有一点需要考虑,从本质上来说,ObservableCollection不是安全的!!

因此,我认为在您的情况下,实施主从方法比较合适((您将有2个数据网格:-首先是通用的,代表您的词典数量,其次是通过KeyValueHolder列表详细列出)

.

But one moment to consider, by it''s nature ObservableCollection is not Thraed-safe!!

So , in your scenario i think , would be prafarable to implements master-details approach,(you will have 2 datagrids: - first is general, represent number of your dictionaries, and second one is detailed by list of KeyValueHolder)


谢谢.这就是我的解决方法.
Thanks. This is how i resolve it.
table = new DataTable();
            dgSearchResult.Columns.Clear();
            string broker = string.Empty;
            string producttype = string.Empty;
            string currency = string.Empty;
            string productsubtype = string.Empty;

            if (cmbProductTypes.SelectedValue != null)
                producttype = cmbProductTypes.SelectedValue.ToString();
            else
                producttype = "";

            if (cmbBrokers.SelectedValue != null)
                broker = cmbBrokers.SelectedValue.ToString();
            else
                broker = "";

            if (cmbProductSubtype.SelectedValue != null)
                productsubtype = cmbProductSubtype.SelectedValue.ToString();
            else
                productsubtype = "";

            if (cmbCurrency.SelectedValue != null)
                currency = cmbCurrency.SelectedValue.ToString();
            else
                currency = "";
//Sample is a list of dict of string string
            List<dictionary><string,string>> sample = Models.RateCards.GetCard(producttype,broker,productsubtype,currency);

            foreach (Dictionary<string,> d in sample)
            {
                foreach (string key in d.Keys)
                {
                    Addcolumn(key);
                }

            }

            foreach (Dictionary<string,> d in sample)
            {
                //Addrow(d);

                row = table.NewRow();
                foreach (KeyValuePair<string,> keyValue in d)
                {
                    if (table.Columns.Contains(keyValue.Key))
                    {
                        if (keyValue.Key != "XMLDefinition")
                        {
                            if (keyValue.Value.Contains(","))
                            {
                                //if (keyValue.Key == "Volume Band Rates" || keyValue.Key == "Premium Band Rates")
                                    row[keyValue.Key] = RemoveSpecialCharacters(keyValue.Value.Replace("}, ", "}" + System.Environment.NewLine).Replace(",", ";").Replace("{", "").Replace("}", "").Replace("[", "").Replace("]", "").Replace("''''", ""));
                                //else
                                //    row[keyValue.Key] = RemoveSpecialCharacters(keyValue.Value.Replace(",", ";").Replace("{", "").Replace("}", "").Replace("[", "").Replace("]", "").Replace("''''", ""));
                            }
                            else
                                row[keyValue.Key] = RemoveSpecialCharacters(keyValue.Value);
                        }
                        else
                            row[keyValue.Key] = keyValue.Value;
                    }
                }

                table.Rows.Add(row);

            }
            
            dgSearchResult.ItemsSource= table.DefaultView;
            
       }

       private static string RemoveSpecialCharacters(string str) 
        {
            StringBuilder sb = new StringBuilder();
            foreach (char c in str) 
            {
                if (c != ''"'') 
                {
                    sb.Append(c);
                }
            }
            return sb.ToString();
        }

        private void Addcolumn(string columnname)
        {
            if (!table.Columns.Contains(columnname))
            {

                DataGridTextColumn dgColumn = new DataGridTextColumn();
                dgColumn.Header = columnname;
                dgColumn.Binding = new Binding(string.Format("[{0}]", columnname));
                dgColumn.SortMemberPath = columnname;
                dgColumn.IsReadOnly = true;
                
                dgSearchResult.Columns.Add(dgColumn);
                
                DataColumn dtcolumn = new DataColumn();
                dtcolumn.Caption = columnname;
                dtcolumn.ColumnName = columnname;
                
                table.Columns.Add(dtcolumn);
                if (columnname == "_id" || columnname == "XMLDefinition")
                    dgColumn.Visibility = Visibility.Hidden;
                    
            }
        }</dictionary>


这篇关于在运行时将字典列表绑定到WPF DataGrid的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆