Putting elements via array into a Listbox - c#

first show my code:
datTable = new DataTable();
sqlCmd = new SqlCommand("SELECT [CustomerId] FROM
[DataSource]", connection);
sqlDatAdapter = new SqlDataAdapter(sqlCmd.CommandText, connection);
sqlDatAdapter.Fill(datTable);
customer.DisplayMember = "CustomerId";
customerListbox.DataSource = datTable;
So that works fine to fill the Listbox with a column from a database in SQL. What I wanted to do is a loop where he automatically fills in more than one Listbox. It works for loop with the SQL Statements but how can I handle the line
customer.DisplayMember = "CustomerId"
Is there a way or have I to duplicate this piece of code over and over again and change the lines manually? I tried to create an array of objects and fill it with customer.DisplayMember etc but that does not work.
What I mean is: I will do this piece of code more than once and everytime just the Listbox and the SQL Column changes. So fill different Listboxes with different columns. So maybe an array or a list with objects like
customer.DisplayMember, product.DisplayMember etc

If I understand what you mean, you want to populate multiple list boxes. You could create a method to populate all the list boxes by passing in a dictionary of the list boxes/data member, and the datatable. Something like this:
private void PopulateListBoxes(Dictionary<ListBox, string> ListBoxCollection, DataTable CustomerTable)
{
foreach(var key in ListBoxCollection.Keys)
{
key.DisplayMember = ListBoxCollection[key];
key.DataSource = CustomerTable;
}
}
And you could call like this:
//this DataTable should contain data for all list boxes
sqlDatAdapter.Fill(dataTable);
Dictionary<ListBox, string> myListBoxes = new Dictionary<ListBox, string>();
//add your existing list boxes here with the corresponding data member
myListBoxes.Add(customerListBox, "CustomerID");
myListBoxes.Add(productListBox, "ProductID");
//add more here
PopulateListBoxes(myListBoxes, dataTable);

Related

Using a list retrieved from a SQLite query in a 'foreach' statement

I'm currently converting some code that stores data in an XML file to storing it in a SQLite database instead. The database has a single table with 4 columns:
thumbnail | title | threadid | url
All of the entries in the database are strings. With my old code, I extract all the data from an XML file and populate a datagrid with the values. My aim is to do just that but using data pulled from the SQLite database. I can successfully extract all the data from the database table like so:
public List<Database> getFromTable()
{
List<Database> items = new List<Database>();
string sql = "SELECT * FROM blacklist";
SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
using (SQLiteDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
var item = new Database();
item.imgstring = (string)reader["thumbnail"];
item.titlestring = (string)reader["title"];
item.threadidstring = (string)reader["threadid"];
item.urlstring = (string)reader["url"];
items.Add(item);
}
}
return items;
}
The part I'm now stuck on is how to use the results returned in the list. Currently I'm calling the method like so:
var items = database.getFromTable();
However after failing to find some examples, I can't work out how to put the foreach line together use the items in the returned list. Eg;
foreach (??? in items)
{
// Populate line in datagrid with thumbnail, title, threadid, url
}
I can get the datagrid populated, it's just understanding how to breakdown my 'items' into a usable form. Any pointers appreciated.
Edit I will be adding this information into a data-grid so each cell value from the SQLite table will be added into a matching cell on the data-grid.
Edit 2 It's worth mentioning that while thumbnail from my SQLite database is a string value, it's actually an image that's been converted to a Base64ImageRepresentation so I can store it as a string value. Part of getting each value from the SQLite database is so I can convert this string back to an image before adding in into my DataGridView.
It would be easier to forego the custom objects, and instead just read a DataTable and use it as the source of the DataGridView directly.
If you must use the custom objects, then you will have to loop over them, create rows from the grid's data source, and populate the rows one by one, adding them back once populated.
Something like this:
foreach (var item in getFromTable())
{
var index = grid.Rows.Add();
var row = grid.Rows[index];
row.SetValues(item.imgstring, item.titlestring, item.threadidstring, item.urlstring); //order of the items must match field order in grid
}
Still, I would opt for the option of binding to a solid data source. But this should give you the general idea.

Dependant dropdownlist(cascading)

I have an existing dropdownlist that lists names.
I am trying to create another drop down list that contaings all Alphabets
What i am trying to accomplish is:
When a user selects an alphabet from the Alphabet Dropsownlist, the second dropdwonlist will populate all the names that start with the selected Alphabets.
I had this code.
`NamesDropDownList.SelectedValue = (NamesDropDownList.DataValueField).Where(NamesDropDownList.SelectedItem.Value).Contains(AlphabetsDropDownList.SelectedItem.Value);`
but it is giving me an error:
Error Message: string does not contain a definition of Where, and the method overload contains invalid arguments.
Any Help Or approach to this problem.
thanks
There are several things wrong with that one line of code. Let's start with the source of the data. This is not the source of your data:
NamesDropDownList.DataValueField
That's just a string property on a DropDownList. You can't select records from that, you have to select them from the database (or wherever your backing data is). You haven't provided that context, so I'm going to suppose it's some standard LINQ-queryable data source. Let's say, for the sake or example, that it's something like this:
dbContext.Names
That is what you'd attach a "where" clause to in order to select data. So now let's move on to that clause and see what it looks like. For starters, it doesn't look like this:
.Where(NamesDropDownList.SelectedItem.Value).Contains(AlphabetsDropDownList.SelectedItem.Value)
The .Where() method doesn't expect a string, it expects a Func<T, bool> as a predicate. Inside that predicate is where you'd have your .Contains(), which would operate on the string and not on the whole collection. So it might look something like this:
dbContext.Names.Where(n => n.Name.Contains(AlphabetsDropDownList.SelectedItem.Value))
What this line of code essentially does is:
From the Names table in the database, select all records where the Name column contains the given value.
That would give you the filtered set of records from the data source, which could then be used to bind to the next DropDownList.
Look into creating an event handler on the parent DDL
Dynamic DDL Event Handler
DropDownList Change Event
Just have the SelectedIndexChanged() event handler from the alphabet dropdownlist populate the names list:
private DataSet GetNameData()
{
string sql = "select Firstname, Lastname from Names where Firstname like '#Letter%';";
SqlParameter arg = new SqlParamter("#Letter", ddlLetter.SelectedItem.Value));
SqlCommand cmd = new SqlCommand, sql, ConnectionString);
cmd.Paramters.Add(arg);
SqlDataAdapter da = new SqlDataAdapter();
DataSet ds = new DataSet();
da.SelectCommand = cmd;
da.Fill(ds);
return ds;
}
private void ddlLetter_SelectedIndexChanged(object sender, EventArgs e)
{
DataSet Names = GetNameData();
ddlNames.DataSource = Names.Table[0];
ddlNames.DataTextField = "Firstname";
ddlNames.DataValueField = "Id";
ddlNames.DataBind();
ddlNames.Items.Insert(0, new ListItem("Please select a name", 0);
}
Make sure you have the alphabet dropdownlist set with AutoPostBack="true" otherwise it won't work.
Hope this helps!

DataGridView bound with binding list displays blank rows

I have table in my database stored in SQL Server 2012 and through this table I am iterating and adding new object in my binding list. This list is then set as datasource for my DataGridView.
As I understand, the DataGridView should create columns and fill the rows with data, but when I run the build, I only see blank rows. Their count is matching the count of rows in table and I also debugged with breakpoints so I have determined that I really have my datasource filled with data, but I cannot figure those blank rows out.
This is method I use for creating dataset and filling the binding list
public void selectCars()
{
string connString = #"Data Source=POHJOLA\SQLEXPRESS;Initial Catalog=BlueCars;Integrated Security=True";
using (SqlConnection connection = new SqlConnection(connString))
{
connection.Open();
string query = "SELECT * FROM Car ORDER BY CarID ASC";
SqlCommand command = new SqlCommand(query, connection);
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
using (DataSet result = new DataSet())
{
adapter.Fill(result);
foreach (DataRow row in result.Tables[0].Rows)
{
carsList.Add(new Car(Convert.ToInt32(row[0]), row[1].ToString(), row[2].ToString(), row[3].ToString(), Convert.ToDecimal(row[4]),Convert.ToInt32(row[5]),row[6].ToString(),row[7].ToString() ));
}
}
}
}
This is my initialization
public managerCarForm()
{
InitializeComponent();
selectCars();
carsGrid.DataSource = carsList;
}
Also I should probably add, that I created columns manually in designer and set datanameproperty to parameters of the car class
I am not getting any exception or error here..
Thanks very much in advance!
I came across the exact same problem in VB.
I Found out that the solution was this:
(I´ll just write my code in VB you can translate it).
Before setting the DataSource of the grid, you should Clear the grid out.
carsGrid.DataSource = Nothing
carsGrid.Rows.Clear()
carsGrid.Columns.Clear()
Then set your grid DataSource as usual. In My case:
carsGrid.DataSource = GetEmptyObject._Get()
Hope it Helps.
foreach (DataRow row in result.Tables[0].Rows)
{
carsList.Add(new Car(Convert.ToInt32(row[0]), row[1].ToString(), row[2].ToString(), row[3].ToString(), Convert.ToDecimal(row[4]),Convert.ToInt32(row[5]),row[6].ToString(),row[7].ToString() ));
}
Please check your carList by applying a breakpoint after foreach loop to verify it contains at least a single data row. And also check your query.
If your application is an ASP.NET
try to modify your code as below..
public managerCarForm()
{
InitializeComponent();
selectCars();
carsGrid.DataSource = carsList;
carsGrid.Databind();
}
Normally this happens when you have manually added the columns in design time.
Or you have AutoGenerateColumns = false;
If you use AutoGenerateColumns = true; the columns will be/should be auto generated.
To solve this:
Right click on the grid -> Edit Columns.
Go to property: DataPropertyName
Set that to the variable name that you bind to (the table column name in your case).
(You say you have done that, but the value here should exactly match what you have in your list. I have made a DTO class and via a loop I have populated a List of my own and set the names to match the properties of that DTO. This should solve it for you.)

Fill ComboBox inside a DataGridView with two Different Tables in C#?

I am capable of filling ComboBox with one Datatable. But i am not able to fill the same combobox with another datatable during runtime. First dataTable and Second Datatable contains different Data with Same Columns.
dtOne= abcd.RetrivData();
cnsmNm.DataSource = dtOne;
cnsmNm.DisplayMember = "One_Name";
cnsmNm.ValueMember = "One_Id";
second datatable
dtSecond= efgh.RetrivData();
cnsmNm.DataSource = dtSecond;
cnsmNm.DisplayMember = "One_Name";
cnsmNm.ValueMember = "One_Id";
You can use DataTable.Merge method. Like this:
dtOne.Merge(dtSecond);
cnsmNm.DataSource = dtOne;

How to add new row to datagridview?

I have DataGridView filled with data from datasource (SQL). Now I want to a add new row, but I can't, because new data can't be added to bounded DataGridView...
I was trying to :
dataGridView1.Source = null;
dataGridView1.Rows.Add("1");
but it clears my previous data in table. How to do it, to add new row without deleting previous data?
When you set the DataSource property to null, you are essentially removing all data from the DataGridView (since it doesn't know what to bind to anymore).
You have two options here. The first is to update the underlying data source. Let's assume that it's a DataTable. In this case, you'd do something like:
DataTable dt = dataGridView1.Source as DataTable;
dt.Rows.Add(new object[] { ... });
And then the DataGridView will pick up on the changes (note that if you are not binding to something that doesn't implement the INotifyCollectionChanged interface, you'll have to call the ResetBindings method to get the grid to refresh).
The other option is to let the DataGridView manage the rows. You can do this by manually adding each item using the Add method on the DataGridViewRowCollection returned by the Rows property:
foreach (var item in source)
{
dataGridView1.Rows.Add("1", "2", "3", ...);
}
I wouldn't say the second solution is optimal, but it will work.
Finally, assuming you are binding to a DataTable (or some other materialization of the data from an underlying data source), this doesn't do anything about to updating underlying data source (that would be a separate question).
The short answer is, you don't.
When you set your DataSource to null, you've broken the link between your DataGridView and your data source, so its data won't be persisted. You can't add a row to a bound DataGridView because it's supposed to represent the state of the underlying DataSource; you're effectively asking .net to make your table out of sync with its backing store, defeating the purpose of databinding in the first place.
If you want to add a row to the backing store, you should be adding a row in the DataSource, not in your DataGridView.
maybe you want to do it manually and detailed? Something like this?
DataSet ds = new DataSet();
OleDbDataAdapter adapter = null;
adapter = new OleDbDataAdapter("SELECT * FROM WHERE", conn);
adapter.Fill(ds);
dataGridView1.ColumnCount = 5; //how many columns returns your SQL query? starts with 0
dataGridView1.Columns[0].Name = "COl-1";
dataGridView1.Columns[1].Name = "COl-2";
dataGridView1.Columns[2].Name = "COl-3";
dataGridView1.Columns[3].Name = "COl-4";
dataGridView1.Columns[4].Name = "COl-5";
DataTable dt = ds.Tables[0];
foreach (DataRow dr in dt.Rows)
{
dataGridView1.Rows.Add(
(dr["COL_HEADER_NAME1"].ToString()),
(dr["COL_HEADER_NAME2"].ToString()),
(dr["COL_HEADER_NAME3"].ToString()),
(dr["COL_HEADER_NAME4"].ToString()),
(dr["COL_HEADER_NAME5"].ToString()));
}
You just add rows by using add method of rows collection
me.datagridview1.rows.add("first","second","third");
You can add any amount of items with array collection.

Categories