Winform, ListBox datasource to Dictionary<string, string> conversion? - c#

In winform application, binding the Listbox with Dictionary via BindingSource property.
How do I get this BindingSource back to original Dictionary by type casting?
Eg:
Dictionary<string, string> objDic = getData();
OrderedDictionry ord = GetOrderedDict(objDic)
listBox.DataSource = new BindingSource(ord , null);
listBox.DisplayMember = "Value";
listBox.ValueMember = "Key";
Now, I want same Dictionary type value from listBox.DataSource for Linq query!!.
Eg:
var r = from t in (listBox.DataSource as Dictionary<string, string>).AsEnumaerable()
select t;
throws error?
How to type cast to dictionary ?

You're trying to cast a BindingSource to a Dictionary. You need to cast the BindingSource's DataSource.
I don't think you can cast from OrderedDictionary to Dictionary<>, but it would be easy to just reconstruct the Dictionary<string, string>:
BindingSource bs = (BindingSource)listBox1.DataSource;
OrderedDictionary ord = (OrderedDictionary)bs.DataSource;
Dictionary<string, string> dict = new Dictionary<string, string>();
foreach (DictionaryEntry item in ord)
dict.Add(item.Key.ToString(), item.Value.ToString());
If you want a LINQ version, you could do:
BindingSource bs = (BindingSource)listBox1.DataSource;
OrderedDictionary ord = (OrderedDictionary)bs.DataSource;
var dict = ord.Cast<DictionaryEntry>().ToDictionary(d => d.Key, d => d.Value);

EDIT 2 - after further discussion/checks:
Dictionary<string, string> A = (from t in ((OrderedDictionary)(((BindingSource)listBox1.DataSource).DataSource)).Cast<KeyValuePair<string, string>>() select t).ToDictionary(d => d.Key, d => d.Value);

Related

C#: Intersect a dictionary with a list. Return dictionary item after match

how can I safety return the dictionary item which matches with the item from the list?
static void Test()
{
var dict = new Dictionary<string, string>();
dict.Add("license1", "123");
dict.Add("license2", "456");
dict.Add("license3", "789");
var list = new List<string>();
list.Add("444");
list.Add("111");
list.Add("123");
var result = dict.Values.Intersect(list);
//result should be only the matching item as a dictionary for dict -> for this example = "license1, 123"
}
Because the dictionary isn't arranged helpfully I think I might do:
var h = list.ToHashSet();
var result = dict.Where(kvp => h.Contains(kvp.Value));

Setting data source for a combobox [duplicate]

I'm using .NET 2.0 and I'm trying to bind a combobox's Datasource to a sorted dictionary.
So the error I'm getting is "DataMember property 'Key' cannot be found on the Datasource".
SortedDictionary<string, int> userCache = UserCache.getSortedUserValueCache();
userListComboBox.DataSource = new BindingSource(userCache, "Key"); //This line is causing the error
userListComboBox.DisplayMember = "Key";
userListComboBox.ValueMember = "Value";
SortedDictionary<string, int> userCache = new SortedDictionary<string, int>
{
{"a", 1},
{"b", 2},
{"c", 3}
};
comboBox1.DataSource = new BindingSource(userCache, null);
comboBox1.DisplayMember = "Key";
comboBox1.ValueMember = "Value";
But why are you setting the ValueMember to "Value", shouldn't it be bound to "Key" (and DisplayMember to "Value" as well)?
I used Sorin Comanescu's solution, but hit a problem when trying to get the selected value. My combobox was a toolstrip combobox. I used the "combobox" property, which exposes a normal combobox.
I had a
Dictionary<Control, string> controls = new Dictionary<Control, string>();
Binding code (Sorin Comanescu's solution - worked like a charm):
controls.Add(pictureBox1, "Image");
controls.Add(dgvText, "Text");
cbFocusedControl.ComboBox.DataSource = new BindingSource(controls, null);
cbFocusedControl.ComboBox.ValueMember = "Key";
cbFocusedControl.ComboBox.DisplayMember = "Value";
The problem was that when I tried to get the selected value, I didn't realize how to retrieve it. After several attempts I got this:
var control = ((KeyValuePair<Control, string>) cbFocusedControl.ComboBox.SelectedItem).Key
Hope it helps someone else!
var colors = new Dictionary < string, string > ();
colors["10"] = "Red";
Binding to Combobox
comboBox1.DataSource = new BindingSource(colors, null);
comboBox1.DisplayMember = "Value";
comboBox1.ValueMember = "Key";
Full Source...Dictionary as a Combobox Datasource
Jeryy
userListComboBox.DataSource = userCache.ToList();
userListComboBox.DisplayMember = "Key";
A dictionary cannot be directly used as a data source, you should do more.
SortedDictionary<string, int> userCache = UserCache.getSortedUserValueCache();
KeyValuePair<string, int> [] ar= new KeyValuePair<string,int>[userCache.Count];
userCache.CopyTo(ar, 0);
comboBox1.DataSource = ar; new BindingSource(ar, "Key"); //This line is causing the error
comboBox1.DisplayMember = "Value";
comboBox1.ValueMember = "Key";
I know this is a pretty old topic, but I also had a same problem.
My solution:
how we fill the combobox:
foreach (KeyValuePair<int, string> item in listRegion)
{
combo.Items.Add(item.Value);
combo.ValueMember = item.Value.ToString();
combo.DisplayMember = item.Key.ToString();
combo.SelectedIndex = 0;
}
and that's how we get inside:
MessageBox.Show(combo_region.DisplayMember.ToString());
I hope it help someone
If this doesn't work why not simply do a foreach loop over the dictionary adding all the items to the combobox?
foreach(var item in userCache)
{
userListComboBox.Items.Add(new ListItem(item.Key, item.Value));
}
Use -->
comboBox1.DataSource = colors.ToList();
Unless the dictionary is converted to list, combo-box can't recognize its members.
Just Try to do like this....
SortedDictionary<string, int> userCache = UserCache.getSortedUserValueCache();
// Add this code
if(userCache != null)
{
userListComboBox.DataSource = new BindingSource(userCache, null); // Key => null
userListComboBox.DisplayMember = "Key";
userListComboBox.ValueMember = "Value";
}

How to get all DataColumns of a DataTable to Lists

I want to get all DataColumns (of double type) of my DataTable in Lists and then create a Dictionary where the Key would be the header of the DataColumn and the Value would be the List with the data of the DataColumn. How can I achieve this with LINQ?
I tried the following lines without success:
// Create Dictionary
Dictionary<string, List<double>> DataDic = new Dictionary<string, List<double>>();
// Create List
List<double> DataList = new List<double>();
// For each DataColumn save it as a List of double
DataList = (from DataColumn dc in dt.Columns select new double()).ToList();
// Add KVP to DataDic
DataDic.Add(column.ColumnName, DataList);
Thanks in advance.
That is pretty straight forward:
// Create Dictionary
var DataDic = dt.Columns.Cast<DataColumn>()
.Where(dc => dc.DataType == typeof(double))
.ToDictionary(dc => dc.ColumnName,
dc => dt.AsEnumerable()
.Select(r => r.Field<double>(dc.ColumnName))
.ToList()
);

How can I get datatable into Dictionary class?

In a windows form application (c#) I've a DataTable. This solution has a class called "AddressStandarizationSolution". What I'm trying to do is load my dictionary from my DataTable that is in the main form.
How could I do that?
public class AddressStandardizationSolution
{
public Dictionary<string, string> directionals = new Dictionary<string, string>();
public Dictionary<string, string> streetName= new Dictionary<string, string>();
public AddressStandardizationSolution()
{
var _with1 = directionals;
_with1.Add("E", "E");
_with1.Add("EAST", "E");
_with1.Add("E-R", "EAST");
_with1.Add("N", "N");
_with1.Add("NO", "N");
var _with2 = streetName;
//This DataTable has 100.000 records
_with1.Add(errorFromDataTable, rightFromDataTable);
}
}
I'm sorry. My DataTable fields are:
error | right
MNTGoMRY AVEnue | MONTGOMERY AVE
You could use Linq to do it. For example:
Dictionary<string, string> resultDictionary = dataTable.Rows.OfType<System.Data.DataRow>()
.Select( s =>
new
{
Error = s["Error"] as string,
Right = s["Right"] as string
}
).ToDictionary( k => k.Error, v => v.Right );
Just an alternative, although it can be combined with Mike Peterson's answer :)
table.AsEnumerable()
.Select(x => new KeyValuePair<string, string>(x.Field<string>("Error"), x.Field<string>("Right")))
.ToDictionary(x => x.Key, x => x.Value);

Query a Dictionary of Dictionaries?

Please can you advise me on how to query a Dictionary of Dictionaries, and/or a Dictionary of List?
private Dictionary<string, Dictionary<DateTime, double>> masterDict= new Dictionary<string, Dictionary<DateTime, double>>();
Private Dictionary<string, List<DateTime>> masterList= new Dictionary<string, List<DateTime>>();
I know if I do the following, I get a list of the dictionaries contained in masterDict, but I'm not sure how to get at the values of those dictionaries.
foreach (var kvp in masterDictMethod())
{
Console.WriteLine("Key = {0}, Value = {1}",
kvp.Key, kvp.Value);
}
Thanks for looking ;)
In you foreach kvp.Value is the inner dictionary of every masterDict entry i.e. Dictionary<DateTime, double>
So, just foreach also over kvp.Value and you will get the inner values.
e.g.
foreach (var kvp1 in masterDictMethod())
{
Console.WriteLine("Key = {0}, Inner Dict:", kvp1.Key);
foreach (var kvp2 in kvp1.Value)
{
Console.WriteLine("Date = {0}, Double = {1}", kvp2.Key, kvp2.Value);
}
}
Use masterDict.Values
This one is:
var masterDictionary = new Dictionary<string, Dictionary<DateTime, double>>();
var query =
from kvp1 in masterDictionary
from kvp2 in kvp1.Value
select new {TheString = kvp1.Key, TheDate = kvp2.Key, TheDouble = kvp2.Value };
foreach(var x in query)
{
Console.WriteLine("{0} {1} {2}", x.TheString, x.TheDate, x.TheDouble);
}
And then the other one is:
var masterList= new Dictionary<string, List<DateTime>>();
var query =
from kvp in masterList
from val in kvp.Value
select new {TheString = kvp.Key, TheDate = val);
foreach(var x in query)
{
Console.WriteLine("{0} {1}", x.TheString, x.TheDate);
}
foreach (var key in masterDict.Keys)
{
var nestedDict = masterDict[key];
}
You asked about lists, dictionaries and dictionaries containing other dictionaries.
I had a similar topic recently, where I wanted to have a queryable dictionary (i.e. an extension method which allows to pass a query expression as lambda parameter), that you can use like:
var result = myDictionary.QueryDictionary(w => myList.Any(a => a == w.Key));
The purpose of this code line is to check if any key of the dictionary is contained in myList.
So what I did is this, I wrote the following extension method:
// extension method using lambda parameters
public static Dictionary<string, T> QueryDictionary<T>(
this Dictionary<string, T> myDict,
Expression<Func<KeyValuePair<string,T>, bool>> fnLambda)
{
return myDict.AsQueryable().Where(fnLambda).ToDictionary(t => t.Key, t => t.Value);
}
It can be used for every dictionary which has keys of type string and items of every object type T.
Now you can easily write queries by passing a lambda expression, as in the following example:
var list1 = new List<string>() { "a", "b" };
var myDict = new Dictionary<string, object>();
myDict.Add("a", "123"); myDict.Add("b", "456"); myDict.Add("c", "789");
var result = myDict.QueryDictionary(w => list1.Any(a => a == w.Key));
The result will contain items a and b, because they are contained in list1.
You can also query a dictionary of dictionaries, here's a C# example for LinqPad, but it can be used as a console application as well (just comment out the .Dump() statements and replace them by Console.WriteLine(...) statements):
void Main()
{
// *** Set up some data structures to be used later ***
var list1 = new List<string>() { "a", "b", "d" }; // a list
var myDict = new Dictionary<string, object>(); // the dictionary
myDict.Add("a", "123"); myDict.Add("b", "456"); myDict.Add("c", "789");
var myDict2 = new Dictionary<string, object>(); // 2nd dictionary
myDict2.Add("a", "123"); myDict2.Add("b", "456"); myDict2.Add("c", "789");
myDict.Add("d", myDict2); // add 2nd to first dictionary
// *** 1. simple query on dictionary myDict ***
var q1 = myDict.QueryDictionary(w => list1.Any(a => a == w.Key));
q1.Dump();
// *** 2. query dictionary of dictionary (q3 contains result) ***
var q2 =
(Dictionary<string, object>)q1.QueryDictionary(w => w.Key.Equals("d")).First().Value;
var q3 = q2.QueryDictionary(w => w.Key.Equals("b"));
q3.Dump();
}
// *** Extension method 'QueryDictionary' used in code above ***
public static class Extensions
{
public static Dictionary<string, T> QueryDictionary<T>(
this Dictionary<string, T> myDict,
Expression<Func<KeyValuePair<string, T>, bool>> fnLambda)
{
return myDict.AsQueryable().Where(fnLambda).ToDictionary(t => t.Key, t => t.Value);
}
}
Since this solution is using Generics, you can pass any lambda expression as search parameter, so it is very flexible.

Categories

Resources