Is there an way of storing both the ID and Test ID values in the Dropdown list but I need to display the DisplayName? I need both of these values when the item is selected
ID | TestID | DisplayName
1 | 2 | Test
Sample Code:
ddList.DataSource = DvName;
ddList.DataTextField = "DisplayName";
ddList.DataValueField = "ID"; // + "TestID" ???
You could use a delimiter to put both values together and then delimit them once you pull them out.
ddList.DataValueField = obj.ID + "~" + obj.TestID;
Otherwise you could create a dictionary that hold the ID and the Test ID, so that when you select your item from the dropdown, you can use the value field as the key to the dictionary and select the TestID.
private Dictionary<string, string> referenceValues = new Dictionary<string, string>();
referenceValues.Add("ID", "TestID");
ddList.DataValueField = "ID";
//When pulling then value back
var referencedItem = referenceValues[ddList.selectedValue];
Assuming you're getting this values from a model you could do something like:
public string NewValue
{
get
{
return ID+ "," + TestId;
}
}
ddList.DataSource = DvName;
ddList.DataTextField = "DisplayName";
ddList.DataValueField = "NewValue";
Assuming that you are using a class for each instance of your data; add another property to the class and bind to that property:
public class MyObject
{
//other stuff
public string DisplayValue
{
get { return String.Format("{0} ({1})", ID, TestID); }
}
}
ddList.DataSource = DvName;
ddList.DataTextField = "DisplayName";
ddList.DataValueField = "DisplayValue";
Related
I have a dictionary containg a string as TKey and a class "Component" as TValue.
My problem is that a want to add database values and xml values into the class fields.
This is my class Component:
public class Component
{
public string ComponentNr { get; set; }
public string Omschrijving { get; set; }
public int Aantal { get; set; }
public int Pos { get; set; }
}
I already have filled the fields ComponentNr and Pos with xml attribute values and now i want to get the "Aantal" and "Omschrijving" from the database where Database value "artcode" is ComponentNr
the query:
SqlCommand dgCommand = new SqlCommand("select g.artcode, i.Description, sum(g.aantal*-1) as aantal " +
"from gbkmut g " +
"join Items i on g.artcode = i.ItemCode " +
"where 1=1 and g.project=#projectnr and g.reknr=3000 and g.bud_vers='MRP' and g.operation='VOORSMD' and g.artcode !='H MAN' and i.Description not like 'pcb %' " +
"group by g.artcode, i.Description, g.aantal ", conn);
This is what i have at the moment to fill the Dictionary with xml attribute value:
Dictionary<string, Component> resultaten = componenten;
List<string> files = fileList;
string file;
file = files.Find(x => x.Contains(faberNr));
XDocument xdoc = XDocument.Load(file);
List<Component> components = xdoc.Descendants("Part").Select(x => new Component()
{
ComponentNr = (string)x.Elements().Where(y => y.Attribute("PartsName") != null)
.Select(y => (string)y.Attribute("PartsName")).FirstOrDefault(),
Pos = (int)x.Descendants().Where(y => y.Attribute("Setno") != null)
.Select(y => (int)y.Attribute("Setno")).FirstOrDefault()
}).ToList();
resultaten = components.GroupBy(x => x.ComponentNr, y => y).ToDictionary(x => x.Key, y => y.FirstOrDefault());
return resultaten;
Example:
My expected output is:
Key = 38292000
Value = Component
Aantal = 16
ComponentNr = 38292000
Omschrijving = Omschrijving123
Pos = 12
My actual output is:
Key = 38292000
Value = Component
Aantal = 0
ComponentNr = 38292000
Omschrijving = null
Pos = 12
So, step 1 is to populate a Dictionary<string, Component> from xml. Then step 2 is to run a database query to finish filling out the Component objects that are stored in the Dictionary?
ComponentNr is the key into the Dictionary, and you have ComponentNr from your database query in the "artcode" field, so you would just look up the value from the Dictionary using "artcode" then modify it.
// reader is an instance of SqlDataReader you got from the SqlCommand.
// resultaten is the Dictionary<string, Component> that you populated earlier.
// If these columns can be null in the database, don't forget to check them for DBNull.Value.
string componentNr = Convert.ToString(reader["artcode"]);
if (resultaten.TryGetValue(componentNr, out Component value))
{
value.Aantal = Convert.ToInt32(reader["aantal"]);
value.Omschrijving = Convert.ToString(reader["Description"]);
}
else
{
// Component exists in the database but not in the Dictionary.
}
I am a bit new to Dapper and am trying to find a clean way to pass a filter parameter to SQL Query for a collection with more than one property.
My collection looks like this:
[{
Prop1: 'A Value 1',
Prop2: 'B Value 1'
},
{
Prop1: 'A Value 2',
Prop2: 'B Value 2'
}]
Which should result in a SQL Query looking something like this:
select *
from SampleTable
where
([ColumnA]='A Value 1' and [ColumnB]='B Value 1')
or ([ColumnA]='A Value 2' and [ColumnB]='B Value 2')
Note: Something like whats shown below will not work because the two properties PropA and PropB need to filter together.
string query = #"select *
from SampleTable
where [ColumnA] in (#PropA_Value)
and [ColumnB] in (#PropB_Value)"
con.Query<T>(query, new{PropA_Value = PropA,PropB_Value = PropB}).AsList();
Modeling your filters as a class:
class MyFilterDefinition
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}
Build that dynamic condition using DapperQueryBuilder would be as simple as this:
var myOptions = new List<MyFilterDefinition>()
{
new MyFilterDefinition() { Prop1 = "A Value 1", Prop2 = "B Value 1" },
new MyFilterDefinition() { Prop1 = "A Value 2", Prop2 = "B Value 2" }
}
var query = cn.QueryBuilder($#"
select *
from SampleTable
/**where**/");
// by default multiple filters are combined with AND, so change to OR
query.FiltersType = Filters.FiltersType.OR;
foreach (var option in myOptions)
query.Where($"[ColumnA] = {option.Prop1} AND [ColumnB] = {option.Prop2}");
var results = query.Query<YourPOCO>();
The final result would be this:
select *
from SampleTable
where ([ColumnA]=#p0 AND [ColumnB]=#p1) OR ([ColumnA]=#p2 AND [ColumnB]=#p3)
With the respective parameters #p0 = 'A Value 1', etc..
Disclaimer: I'm the author of DapperQueryBuilder
You can generate filter strings dynamically using the following helper class:
public static class DapperHelper
{
private const string SingleTupleFormat = " [{0}] = '{1}' {2}";
private const string AndString = "AND";
private const string OrString = "OR";
private static string ToSqlTuple(List<Dictionary<string, string>> filters)
{
string filterParam = string.Empty;
foreach (var filter in filters)
{
//Construct single tuple
string tuple = filter.ToList().Aggregate(string.Empty,
(current, pair) => current + String.Format(SingleTupleFormat, pair.Key, pair.Value, AndString));
//Concatenate tuples by OR, string.Format to combine the different filters
filterParam += string.Format(" ({0}) {1}", tuple.TrimEnd(AndString), OrString);
}
return filterParam.TrimEnd(OrString);
}
public static string TrimEnd(this string source, string value)
{
if (!source.EndsWith(value))
return source;
return source.Remove(source.LastIndexOf(value));
}
}
Usage:
string query = #"select *
from SampleTable
where #where";
List<Dictionary<string, string>> filters = new List<Dictionary<string, string>>() {
new Dictionary<string, string>(){{"ColumnA", "A Value 1"},{"ColumnB", "A Value 2"}},
new Dictionary<string, string>(){{"ColumnA", "B Value 1"},{"ColumnB", "B Value 2"}}
};
var tuple = DapperHelper.ToSqlTuple(filters);
query = query.Replace("#where", string.IsNullOrEmpty(tuple) ? "1=1" : tuple); //Use 1=1 if tuple is empty or null
var data = con.Query<T>(query).AsList();
Query string looks like:
select *
from SampleTable
where ( [ColumnA] = 'A Value 1' AND [ColumnB] = 'A Value 2' )
OR ( [ColumnA] = 'B Value 1' AND [ColumnB] = 'B Value 2' )
I am trying to work with Dictionary<> along with List<> for searching purpose. I know, I can do this easily with List<> as follows:
var con = (from c in db.Customers
where c.Status == status
select c).ToList();
But preferred and tried to implement the above with Dictionary<>. My concept (We all know that) is using the key/value will increase the search option performance. This looks simple and stuck a bit. Here what I've tried:
static void Main(string[] args)
{
Dictionary<string, Customer> custDictionary = new Dictionary<string, Customer>(); //Dictionary declared
List<Customer> lst = new List<Customer>(); //List of objects declared
Customer aCustomer = new Customer(); //Customer object created
/**Assign values - Starts**/
aCustomer.CustomerId = 1001;
aCustomer.CustomerName = "John";
aCustomer.Address = "On Earth";
aCustomer.Status = "Active";
aCustomer.CustomerId = 1002;
aCustomer.CustomerName = "James";
aCustomer.Address = "On Earth";
aCustomer.Status = "Inactive";
/**Assign values - Ends**/
custDictionary.Add(aCustomer.Status, aCustomer); //Added to the dictionary with key and value
string status = Console.ReadLine().ToUpper();
if (custDictionary.ContainsKey(status)) //If key found in the dictionary
{
Customer cust = custDictionary[status];
Console.WriteLine(cust.CustomerId + " " + cust.CustomerName); //Outputs the final result - Right now no result found here
}
Console.ReadKey();
}
public class Customer
{
public int CustomerId { get; set; }
public string CustomerName { get; set; }
public string Address { get; set; }
public string Status { get; set; }
}
Unfortunately, the above doesn't return any result. What I am trying is to get customer details by passing status key and again passed Customer object as the value. I am not sure what I am missing here.
One more thing, in real-life projects, we get database results as list. So in this scenario, if Dictionary<> is used, I believe, the database results should be kept as follows:
lst.Add(aCustomer); //As database will have more result or data simply
On the other hand, I believe, the dictionary should look like the below:
Dictionary<string, List<Customer>> custDictionary = new Dictionary<string, List<Customer>>();
My question - Is it a good idea to pass a list of objects in the dictionary for the key/vale pair and I've tried using so. But didn't get the output yet.
Note: This sounds like a novice question and yes, it's. I've tried to search online and still studying it. I apology to ask such a question and would expect some answers if there are any better ways to do the above.
UPDATED
If you want to store them in a list, you can do the following code. To select the items, you can then use Linq, and in this way you don't have the issue of duplicate values in a dictionary:
var lst = new List<Customer>(); //List of objects declared
lst.AddRange(
new List<Customer>() {
new Customer()
{
CustomerId = 1001,
CustomerName = "John",
Address = "On Earth",
Status = "Active"
},
new Customer()
{
CustomerId = 1002,
CustomerName = "James",
Address = "On Earth",
Status = "Inactive"
}
}
);
var status = Console.ReadLine();
var selected = lst.Where(x => x.Status.ToUpper() == status.ToUpper()).ToList();
foreach (var item in selected)
{
Console.WriteLine(item.CustomerId + " " + item.CustomerName);
}
UPDATE 2
If you want to add the above list in a dictionary, you can do as follows:
var custDictionary = new Dictionary<string, List<Customer>>();
// the above code for the list
custDictionary.Add("keyname", lst);
ORIGINAL ANSWER
You are saving one customer only since you are overwriting the first customer with the second one:
Dictionary<string, Customer> custDictionary = new Dictionary<string, Customer>();
List<Customer> lst = new List<Customer>();
// Add first customer
var aCustomer = new Customer()
{
CustomerId = 1001,
CustomerName = "John",
Address = "On Earth",
Status = "Active"
};
custDictionary.Add(aCustomer.Status.ToUpper(), aCustomer);
// Add second customer
var bCustomer = new Customer()
{
CustomerId = 1002,
CustomerName = "James",
Address = "On Earth",
Status = "Inactive"
};
custDictionary.Add(bCustomer.Status.ToUpper(), bCustomer);
Also you need to store the Status as uppercase, since you are checking if the status exist in uppercase:
string status = Console.ReadLine().ToUpper();
if (custDictionary.ContainsKey(status)) //If key found in the dictionary
{
Customer cust = custDictionary[status];
Console.WriteLine(cust.CustomerId + " " + cust.CustomerName); //Outputs the final result - Right now no result found here
}
Console.ReadKey();
If you already has the list and want to create a Dictionary<string, List<Customer>> you can do it with this:
Dictionary<string, List<Customer>> dict =
list.GroupBy(c=>c.Status.ToUpper()).ToDictionary(g => g.Key, g=> g.ToList());
And iterate it:
foreach (var customer in dict[status.ToUpper()])
{
}
But,
I don't see the value in doing so. if you need to get all the customers with a specific status stay with what you have - a simple linq query.
Even if you are adding status as key, there are 2 problems with your code.
You need to create 2 objects to create 2 customers, one by one. You are adding customer only once, and assigning values twice.
Console.ReadLine().ToUpper() - Remove the ToUpper() since you are adding values in mixed case. If you want to do that, initialize dictionary with StringComparer.InvariantCultureIgnoreCase.
This will work for you.
Dictionary<string, Customer> custDictionary = new Dictionary<string, Customer>(StringComparer.InvariantCultureIgnoreCase); //Dictionary declared
List<Customer> lst = new List<Customer>(); //List of objects declared
Customer aCustomer = new Customer(); //Customer object created
/**Assign values - Starts**/
aCustomer.CustomerId = 1001;
aCustomer.CustomerName = "John";
aCustomer.Address = "On Earth";
aCustomer.Status = "Active";
custDictionary.Add(aCustomer.Status, aCustomer); //Added to the dictionary with key and value
Customer bCustomer = new Customer(); //Customer object created
bCustomer.CustomerId = 1002;
bCustomer.CustomerName = "James";
bCustomer.Address = "On Earth";
bCustomer.Status = "Inactive";
custDictionary.Add(bCustomer.Status, bCustomer); //Added to the dictionary with key and value
string status = Console.ReadLine().ToUpper();
if (custDictionary.ContainsKey(status)) //If key found in the dictionary
{
Customer cust = custDictionary[status];
Console.WriteLine(cust.CustomerId + " " + cust.CustomerName); //Outputs the final result - Right now no result found here
}
Console.ReadLine();
First of all your dictionary key should be customerId not status. it will be a good practice to check if dictionary contains the key other wise it will throw the exception already same key is added. so its better to check then perform add or update in the dictionary.
static void Main(string[] args)
{
Dictionary<string, Customer> custDictionary = new Dictionary<string, Customer>(); //Dictionary declared
List<Customer> lst = new List<Customer>(); //List of objects declared
Customer aCustomer = new Customer(); //Customer object created
/**Assign values - Starts**/
aCustomer.CustomerId = 1001;
aCustomer.CustomerName = "John";
aCustomer.Address = "On Earth";
aCustomer.Status = "Active";
if (!custDictionary.ContainsKey(aCustomer.CustomerId))
custDictionary.Add(aCustomer.CustomerId, aCustomer);
else
custDictionary[aCustomer.CustomerId] = aCustomer;
aCustomer.CustomerId = 1002;
aCustomer.CustomerName = "James";
aCustomer.Address = "On Earth";
aCustomer.Status = "Inactive";
/**Assign values - Ends**/
if (!custDictionary.ContainsKey(aCustomer.CustomerId))
custDictionary.Add(aCustomer.CustomerId, aCustomer);
else
custDictionary[aCustomer.CustomerId] = aCustomer;
string status = Console.ReadLine().ToUpper();
if (custDictionary.ContainsKey(aCustomer.CustomerId)) //If key found in the dictionary
{
Customer cust = custDictionary[aCustomer.CustomerId];
Console.WriteLine(cust.CustomerId + " " + cust.CustomerName); //Outputs the final result - Right now no result found here
}
Console.ReadKey();
}
Your are not getting any output because your are converting your input to uppercase while you have insert the keys in pascalcase and in case of C# collections keys are case sensitive. in this way your input does not matched to any key in collection
change your line number : 29 to this code
string status = Console.ReadLine();
and insert "Inactive" from you console this key exist in your collection
so you will desired result..
I've got the following code to populate a combobox with the contents of a generic list, trying to use a concatenation of FirstName and LastName as the combobox's DisplayMember:
private void PopulateStudentsComboBox()
{
if (System.IO.File.Exists(AYttFMConstsAndUtils.STUDENTS_FILENAME))
{
if (null == _studentsList)
{
var students = System.IO.File.ReadAllText(AYttFMConstsAndUtils.STUDENTS_FILENAME);
_studentsList = JsonConvert.DeserializeObject<List<Student>>(students);
}
// Sort by firstname
_studentsList = _studentsList.OrderBy(i => i.FirstName).ToList();
comboBoxStudents.DataSource = _studentsList;
string firstNameLastName = "FirstName LastName";
comboBoxStudents.DisplayMember = firstNameLastName;
comboBoxStudents.ValueMember = "StudentID";
}
}
This doesn't work; the ValueMember becomes the DisplayMember.
This works:
. . .
comboBoxStudents.DataSource = _studentsList;
comboBoxStudents.DisplayMember = "FirstName";
comboBoxStudents.ValueMember = "StudentID";
. . .
...but doesn't cut the mustard - I need both given and surnames, not just the given name (or vice versa).
How can I combine two class fields to comprise a combobox's DisplayMember?
I would extend the Student class with a Property which returns
"FirstName + LastName"
like...
...
public string DisplayName
{
get
{
return string.Format("{0} {1}", this.FirstName, this.LastName);
}
}
...
than assign this property to the DisplayMember
comboBoxStudents.DisplayMember = "DisplayName";
I have combobox in my windows forms app and I want it to have values on particular options.
Now I can only put an option, and when I choose it - I can get it via
combobox.text
My target is to list filenames in combobox and have paths to them in values.
Example: Text is= "option1" value which it contains is = "value1", how to do it?
I saw a few topics about it, but they are about 2 years old, maybe something changed, cause these solutions were not so friendly : ]
UPDATE
I've got one issue with your solution, Mahmoud Gamal : )
I'm doing it this way:
List<Foo> combo3data = new List<Foo>();
categories = Directory.GetDirectories(#"C:\banners\categories\");
// There are 3 different paths in categories[] array (category1, category2 and 3)
Foo categoryInsert = new Foo();
foreach (string s in categories)
{
categoryInsert.path = s;
categoryInsert.name = s;
combo3data.Add(categoryInsert);
}
comboBox3.DataSource = combo3data;
comboBox3.ValueMember = "path";
comboBox3.DisplayMember = "name";
After that my comboBox3 has 3 available options (correct) but all of them are the same (same as option #1) - why is that?
You are looking for the two properties:
ValueMember.
DisplayMember.
In your case, you have to set the combobox's ValueMember property to value1 and the DisplayMember property to option1.
Update: The following is an exmple of how you can populate the items of a combobox from list of some entity Foo:
public class Foo(){
public string Id { get; set; }
public string Name { get; set; }
}
var ds = new List<Foo>(){
new Foo { Id = "1", Name = "name1" },
new Foo { Id = "2", Name = "name2" },
new Foo { Id = "3", Name = "name3" },
new Foo { Id = "4", Name = "name4" },
};
comboboxName.DataSource = ds;
comboboxName.ValueMember = "Id";
comboboxName.DisplayMember = "Name";
Update2: That's because you are adding the same object each time. In the following block of your code:
Foo categoryInsert = new Foo();
foreach (string s in categories)
{
categoryInsert.path = s;
categoryInsert.name = s;
combo3data.Add(categoryInsert);
}
Each time The foreach iterate over the categories, all what it does, is changing the same object categoryInsert's values path and name not creating a new one. Thus, you end up with the same object added in each iteration to the combo3data. What you need is create a new Foo object inside the foreach itself each time, i.e: move the Foo categoryInsert = new Foo(); inside the foreach loop. Something like:
foreach (string s in categories)
{
Foo categoryInsert = new Foo();
categoryInsert.path = s;
categoryInsert.name = s;
combo3data.Add(categoryInsert);
}
use comboBox.Text to set or get the text associated with this combobox.
for Values use comboBox.ValueMember for the actual value for the items in the ListControl
or you could also store the values in the comboBox.Tag