C# Working with mulitcolumn list - c#

I've created a multicolumn list (lstItems) that I want to use for lookups so I don't have to do repeated data queries and I can't figure out how to reference the items/cells. If an alternate structure would be better/easier, I'm open to suggestions, but this is what I've got so far.
I can query the OLEDB table and populate lstItems but not sure how to reference the elements/cells. As a test I populated listbox1 from the query. Then after building lstItems I echoed back the contents, no problem. Now I need to do two things.
Populate listbox1 with one of the columns from lstItems instead of directly from the query.
Later, be able to query lstItems so when "nameValue" = the second column nameValue, return the corresponding ID.
.
sqlCmd.CommandText = "select ID, Name from table;
OleDbDataReader sqlRead = sqlCmd.ExecuteReader();
// Create a Name/Value list
List<KeyValuePair<string, string>> lstItems = new List<KeyValuePair<string, string>>();
int j = 0;
while (sqlRead.Read())
{
//Populate listbox1 directly from query
string nm= Convert.ToString(sqlRead["Name"]);
listBox1.Items.Add(nm);
// Create the multicolumn list
lstItems.Add(new KeyValuePair<string, string>
(Convert.ToString(sqlRead["ID"]), Convert.ToString(sqlRead["Name"])));
// Echo out to insure the list has the proper values
MessageBox.Show("Show List: " +lstItems [j].ToString());
j++;
}

I like to use DataTables for this sort of thing personally. I will then reference the table instead of the database when I need the data for lookups:
sqlRead = sqlCmd.ExecuteReader();
var dt = new DataTable();
for (var i = 0; i < sqlRead.FieldCount; i++)
{
dt.Columns.Add(sqlRead.GetName(i), typeof(string));
}
while (sqlRead.Read())
{
var row = dt.Rows.Add();
for (var i = 0; sqlRead.FieldCount; i++)
{
var val = sqlRead[i].ToString();
row[i] = val;
}
}
sqlRead.Close();
OR:
// Connection object is the second parameter
using (var a = new SqlDataAdapter("select ID, Name from table", c))
{
var t = new DataTable();
a.Fill(t);
}
Then you can reference the DataTable for data!

Example binding for winforms
private void Form1_Load(object sender, EventArgs e)
{
DataTable oDataTable = new DataTable();
using (SqlConnection oSqlConnection = new SqlConnection(Properties.Settings.Default.ConnectionString))
{
using (SqlCommand oSqlCommand = new SqlCommand("select ProductID, ProductName from Product", oSqlConnection))
{
using (SqlDataAdapter adapter = new SqlDataAdapter(oSqlCommand))
{
adapter.Fill(oDataTable);
}
}
}
listBox1.DisplayMember = "ProductName";
listBox1.ValueMember = "ProductID";
listBox1.DataSource = oDataTable;
}
private void button1_Click(object sender, EventArgs e)
{
DataRowView selectedRow = (DataRowView)listBox1.SelectedItem;
MessageBox.Show(selectedRow["ProductId"].ToString());
}

Related

Binding data from SQL Table to custom list created using user control in C#

I am working a project and i need to display on a form (frmCaterlogs) a list of items. I have successfully implimented a custom list using a user control & FlowLayOutPanel. However now i am stuck on how i can bind my caterlogs that sits on a sql database to my custom list: Here is my code. on the custome_list(CatList), i have 4 controls, Id, Titile, Description, Icon stored in database as binarydata in the sqldb. I am lost on how i can bind data to the custom list control that can look thought all the records in my database. Thanking you all in advace for your kind advices.
private void PopulateCatelog()// This code is triggered when frmcaterlogs loads.
{
int l;
string query = "SELECT * from ServicesCaterlogs";
SqlConnection con = new SqlConnection(cn);
SqlCommand cmd = new SqlCommand(query, con);
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
ListView Items = new ListView()
sda.Fill(dt);
l = dt.Rows.Count;
foreach(DataRow dr in dt.Rows) // This is where i am stuck
{
CatList iList = new CatList(dr["Item"].ToString());
iList.Title = dr;
}
CatList[] ListItem = new CatList[l];
//Loop though to check each item
for (int i = 0; i < ListItem.Length; i++)
{
ListItem[i] = new CatList();
ListItem[i].Title = fetch data for a list;
ListItem[i].Message = "fetch data for a lis";
ListItem[i].icon = Resources.Warning;
ListItem[i].IconBackground1 = Color.DarkGoldenrod;
if (FlowLayoutPanel.Controls.Count < 0)
{
FlowLayoutPanel.Controls.Clear();
}
else
{
FlowLayoutPanel.Controls.Add(ListItem[i]);
}
}
I got the desired result after altering the code as seen below
private void FrmCatalogs_Load(object sender, EventArgs e)
{
PopulateCatelog();
}
private void PopulateCatelog()
{
//Populate your listitem here
int l;
string query = "SELECT * from ServicesCaterlogs";
SqlConnection con = new SqlConnection(cn);
SqlCommand cmd = new SqlCommand(query, con);
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
sda.Fill(dt);
l = dt.Rows.Count;
foreach(DataRow dr in dt.Rows)
{
ListViewItem item = new ListViewItem(dr["Item"].ToString());
ListViewItem des = new ListViewItem(dr["Item_Description"].ToString());
CatList[] ListItem = new CatList[l];
for (int i = 0; i < ListItem.Length - l +1 ; i++)
{
ListItem[i] = new CatList();
ListItem[i].Title = item.Text;
ListItem[i].Message = des.Text;
ListItem[i].icon = Resources.Warning;
ListItem[i].IconBackground1 = Color.DarkGoldenrod;
if (FlowLayoutPanel.Controls.Count < 0)
{
FlowLayoutPanel.Controls.Clear();
}
else
{
FlowLayoutPanel.Controls.Add(ListItem[i]);
}
}
}
}

How can add datatable items to list?

I have a database with a table containing 3 columns. I would like to extract data from that table and add to a list.
Here is my code:
private void button1_Click(object sender, EventArgs e)
{
OleDbCommand parancs = kapcsolat.CreateCommand();
parancs.CommandText = "select hossz from artandbihark";
kapcsolat.Open();
OleDbDataReader reader = parancs.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(reader);
dataGridView1.DataSource = dt;
List<double> tavolsag = new List<double>();
for (int i = 0; i < dt.Rows.Count; i++)
{
tavolsag.Add(Convert.ToDouble(dt.Rows[i]));
}
kapcsolat.Close();
}
But I cannot convert dt.Rows[i] to double. How can I finish the above code to add the data correctly?
You only have one property in your DataRow, so that's the 0th property.
tavolsag.Add(Convert.ToDouble(dt.Rows[i][0]));

Additional information: Complex DataBinding accepts as a data source either an IList or an IListSource

I'm trying to select sum of total in excel sheets and add it into a list box, each one of them in a new line.
private void btn_update_Click(object sender, EventArgs e) {
for (int i = list_sheetnames.Items.Count -1; i >= 0; i--) {
string connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + textBox_filename.Text + ";Extended Properties='Excel 12.0 XML;HDR=YES;';";
string selectCmd = "Select SUM(Total) As Total_SUM From [" + list_sheetnames.Items[i] + "$]";
using(OleDbConnection excelConn = new OleDbConnection(connString)) {
excelConn.Open();
OleDbCommand command = new OleDbCommand(selectCmd, excelConn);
OleDbDataAdapter da = new OleDbDataAdapter(command);
DataTable sheetInfo = new DataTable();
da.Fill(sheetInfo);
//Do something with the data.
//list_total.Items.Add(sheetInfo);
list_total.DataSource = da.ToString();
}
}
}
I got an error
It looks like you're trying to bind a datatable to a List. I'm guessing List_total is a List<string>? If you want to add the values from the datatable then you'll need to loop through the rows and the items to get what you want.
foreach (var row in da.Rows)
{
foreach (var item in row.ItemArray)
{
//do your checks on the data here and add it to your list if necessary.
list_total.Add(item.ToString());
}
}
You could also try the traditional for loop like this:
for (int i = 0; i < da.Rows.Count; i++)
{
list_total.Add(da.Rows[i]["Total_SUM"].ToString());
}
UPDATE
So your code is now:
List<string> lst = new List<string>();
foreach (DataRow r in sheetInfo.Rows)
{
string sheettotal = (string)r["Total_SUM"].ToString();
lst.Add(sheettotal);
}
list_total.DataSource = lst;

How do I sort a dataGridView the was populated with SqlDataReader and BindingSource , when i push a button

I am trying to create a sort button , to sort the all ready filtered Data that is in datagridview.
But when i do :
private void comboBox3_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.SelectedItem != null)
{
if (sortComboBox.SelectedItem == "Price low - high")
{
this.dataGridView1.Sort(this.dataGridView1.Columns["Price"], ListSortDirection.Ascending);
}
if (sortComboBox.SelectedItem == "Price high - low")
{
this.dataGridView1.Sort(this.dataGridView1.Columns["Price"], ListSortDirection.Descending);
}
}
else
{
MessageBox.Show("Please select a component");
}
}
Then it Give me an error:
DataGridView control cannot be sorted if it is bound to an IBindingList that does not support sorting.
This is how I populated the dataGridView :
command = new SqlCommand("SELECT [Price],[Mark],[Type],[Code],[Series],[Rating],[Description],[Comments]FROM "+database+" ORDER BY CAST(ID AS INT) ", connection);
SqlDataReader reader = command.ExecuteReader();
// Create a BindingSource object
BindingSource bs = new BindingSource();
// Assign the reader to the binding source
bs.DataSource = reader;
// Assign the BindingSource to the DataGridView DataSource
dataGridView1.DataSource = bs;
reader.Close();
Please help me to show how sort the Data the user have in the dataGridView currently.
P.S. the allowusertoordercolumns is also not working.
I have this but its not working
List<string[]> allDatalist = new List<string[]>();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
string[] rowData = new string[8]; // 8 because you're loading from a table with 8 columns
for (var i = 0; i < rowData.Length; i++)
{
MessageBox.Show(reader.GetString(i));
rowData[i] = reader.GetString(i);
}
allDatalist.Add(rowData);
}
for (var x = 0; x < allDatalist.Count; x++)
{
dataGridView1.Rows.Add(allDatalist[x]);
}
}
reader.Close();
}
So this is merely pseudo-code, but I'm sure you get the idea:
First load everything into a list:
var command = new SqlCommand("SELECT [Price],[Mark],[Type],[Code],[Series],[Rating],[Description],[Comments]FROM "+database+" ORDER BY CAST(ID AS INT) ", connection);
List<object[]> allData = new List<object[]>();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
object[] rowData = new object[8]; // 8 because you're loading from a table with 8 columns
for (var i = 0; i < rowData.Length; i++)
{
rowData[i] = reader.GetObject(i);
}
allData.Add(rowData);
}
}
// Congratulations, you now have a collection containing all the data from your database.
// At this point, you'll want to sort on one of the column (Loop through every row in the allData list, and compare position 0 or 1 or whatever data you want.
Hope this answers your question.
At the end of the day this was all I wanted..
SqlDataAdapter dataAdapter = new SqlDataAdapter(cmd, connectionString);
SqlCommandBuilder commandBuilder = new SqlCommandBuilder(dataAdapter);
DataSet ds = new DataSet();
dataAdapter.Fill(ds);
dataGridView1.ReadOnly = true;
dataGridView1.DataSource = ds.Tables[0];
Now It can be sorted with headers of datagrid.

Delete the single selected row from a grid view at run time

I have a table having 2 columns viz ID and DETAILS.Data in a table is like
id=01 details="pritam=123 sourav=263" like this
i am working on a windows for application ..when the application will run the output comes what i am going to tell.. 1.in my application one combobox is there.when the application will run all the id will be bind in a combobox from the table. 2.when user will choose any id suddenly the details column data will be shown in a datagrid view in a splitted format like this.
NAME KEY
PRITAM 123
SOURAV 263
in this data grid view user can delete ant row by selecting the and click on the below delete button. insert any row by clickng the add new row button at the end ,modify any existing data and finally click on the update button and all the data are going to be stored in that data base like in previous format.. for that i have written the code in c# like this..
namespace windows_csharpp
{
public partial class Form5 : Form
{
SqlConnection cc = new SqlConnection("Integrated Security=true;database=EDIXfer");
SqlDataAdapter da;
DataTable dt;
public Form5()
{
InitializeComponent();
}
private void Form5_Load(object sender, EventArgs e)
{
string sql="select EDIScheduleID from ETAProcessSchedule";
da= new SqlDataAdapter(sql, cc);
dt = new System.Data.DataTable();
da.Fill(dt);
for (int x = 0; x < dt.Rows.Count; x++)
{
comboBox1.Items.Add(dt.Rows[x][0].ToString());
}
}
ArrayList ls = new ArrayList();
int ss = 0;
int ss1 = 0;
int ssp = 1;
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string sql = "select * from ETAProcessSchedule where EDIScheduleID='" + comboBox1.SelectedItem.ToString() + "'";
SqlDataAdapter adp = new SqlDataAdapter(sql, cc);
DataTable dt = new System.Data.DataTable();
adp.Fill(dt);
string stp = dt.Rows[0][21].ToString();
string[] stp1 = stp.Split(' ');
List<Class1> lst = new List<Class1>();
ls.Clear();
for (int x = 0; x < stp1.Length; x++)
{
ls.Add(stp1[x].ToString());
}
for (int x = 0; x < ls.Count; x++)
{
string ssttt = ls[x].ToString();
string[] sssp = ssttt.Split('=');
for (int x1 = 1; x1 < sssp.Length; x1++)
{
ss = 0;
ss1 = ssp;
Class1 cs = new Class1()
{
Value = sssp[ss], Key= sssp[x1].ToString()
};
lst.Add(cs);
}
}
dataGridView1.DataSource = lst;
}
private void Update_Click(object sender, EventArgs e)
{
string value = null;
string keys = null;
string query = null;
string str = null;
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
value = dataGridView1.Rows[i].Cells[0].Value.ToString();
keys = dataGridView1.Rows[i].Cells[1].Value.ToString();
string ss = value + '=' + keys;
str += ss + ' ';
}
query = "update ETAProcessSchedule set ProcParameters='"+str+"' where EDIScheduleID='"+comboBox1.SelectedItem.ToString()+"'";
da = new SqlDataAdapter(query, cc);
dt = new DataTable();
da.Fill(dt);
MessageBox.Show("Data Updated In Database Successfully");
}
and one class file is also there ..
class Class1
{
public string Value { get; set; }
public string Key { get; set; }
}
kindly help me in delete the selected row ,add the new row and update the all data in database like in previous format..
I think you already have working approach. If I understand right you need only two functions:
- Load Schedule details in the DataGridView (one key-value pair per row)
- Save edited/added/deleted key-value pairs to the database
Be sure next properties of DataGridView set to true:
this.YourDataGridView.AllowUserToAddRows = true;
this.YourDataGridView.AllowUserToDeleteRows = true;
And of course columns must be editable
In the methods was used const variables which was created in your Form (Form1)
private const string DETAILSDELIMITER = ' ';
private const string NAMEKEYDELIMITER = '=';
Method for loading schedule details in the DataGridView
//Use SqlParameters in the query,
//if not your application vulnerable for sql injection
private void LoadScheduleDetails(string scheduleID)
{
//You working only with one column, do not use '*' in SELECT statement if not nessesary
string query = "SELECT EDIScheduleID, ProcParameters FROM ETAProcessSchedule WHERE EDIScheduleID = #ScheduleID";
DataTable details = new DataTable();
//Get data from database
using (SqlConnection yourConnection = new SqlConnection(_YourConnectionString))
{
using(SqlCommand detailsCommand = new SqlCommand(query, yourConnection))
{
//Adding parameter
SqlParameter id = new SqlParameter { ParameterName = "#ScheduleID", SqlDbType = SqlDbType.NVarChar, Value = scheduleID };
detailsCommand.Parameters.Add(id);
using (SqlDataAdapter yourAdapter = new SqlDataAdapter(detailsCommand ))
{
yourAdapter.Fill(details);
}
}
}
this.YourDataGridView.Rows.Clear();
if (details.Rows.Count > 0)
{
DataRow temp = details.Rows[0];
//get column by name.
string[] pairs = temp.Field<String>("ProcParameters").Split(Form1.DETAILSDELIMITER);
//Adding rows manually without DataSource
foreach(string pair in pairs)
{
this.YourDataGridView.Rows.Add(pair.Split(Form1.NAMEKEYDELIMITER));
}
}
}
Method for saving data
I think better if you create columns already in the designer
Then you can access columns by it's name without hardcoding indexes
private void SaveDetails(string scheduleID)
{
StringBuilder details = new StringBuilder();
foreach(DataGridViewRow dgvr in this.YourDataGridView.Rows)
{
string name = dgvr.Cells[this.dgvColumn_Name.Name].Value.ToString();
string key = dgvr.Cells[this.dgvColumn_Key.Name].Value.ToString();
//Here you can check if values are ok(not empty or something else)
//Create pair
details.Append(Form1.DETAILSDELIMITER);
details.Append(name);
details.Append(Form1.NAMEKEYDELIMITER);
details.Append(key);
}
//remove first space character
if (details.Length > 0)
details.Remove(0, 1);
//Save data to database
string query = "UPDATE ETAProcessSchedule SET ProcParameters=#Details WHERE EDIScheduleID=#ScheduleID";
using (SqlConnection yourConnection = new SqlConnection(_YourConnectionString))
{
using (SqlCommand saveCommand = new SqlCommand(query, yourConnection))
{
//Adding parameters
SqlParameter id = new SqlParameter { ParameterName = "#ScheduleID", SqlDbType = SqlDbType.NVarChar, Value = scheduleID };
SqlParameter procParams = new SqlParameter { ParameterName = "#Details", SqlDbType = SqlDbType.NVarChar, Value = details.ToString() };
saveCommand.Parameters.Add(id);
saveCommand.Parameters.Add(procParams);
saveCommand.ExecuteNonQuery();
MessageBox.Show("Data Updated In Database Successfully");
}
}
}
Then use LoadScheduleDetails in the comboBox1_SelectedIndexChanged eventhandler
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string scheduleID = comboBox1.SelectedItem.ToString();
if(String.IsNullOrEmpty(scheduleID) == false)
{
this.LoadScheduleDetails(scheduleID);
}
}
After data loaded, user can change it, add rows, delete rows
When user pressed "Update" button then use SaveDetails method,
where we collect data from all rows and update database with it
private void Update_Click(object sender, EventArgs e)
{
string scheduleID = comboBox1.SelectedItem.ToString();
if(String.IsNullOrEmpty(scheduleID) == false)
{
this.SaveDetails(scheduleID);
}
}
On your form load bind data:-
EDIT : -
private void Form5_Load(object sender, EventArgs e)
{
comboBox1.DataSource = loadddltable();
comboBox1.DisplayMember = "Name";
comboBox1.ValueMember = "ID";
}
public DataTable loadddl()
{
OleDbDataReader obj = null;
DataTable dt = new DataTable();
try
{
obj_dbconnection.CommandText = "Select * from TableName";
obj = obj_dbconnection.ExecuteReader();
if (obj != null)
{
if (obj.HasRows)
{
dt.Load(obj);
}
}
}
catch (Exception)
{
}
finally
{
if (obj != null)
{
obj.Close();
obj_dbconnection.Close();
}
}
return dt;
}
/*Code for Execute Reader*/
public OleDbDataReader ExecuteReader()
{
OleDbDataReader dr = null;
try
{
Open();
dr = cmd.ExecuteReader();
}
catch(Exception)
{ }
return dr;
}
/*Code for binding grid data*/
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
dataGridView1.DataSource= getDataForSelectedId(comboBox1.SelectedValue);
}
And then insert,edit,delete buttons as template fields to dataGridView and use dataGridView1_CellClick event to insert edit delete

Categories