Unable to get dropdown selected value - c#

I have a gridview that is populated with a dropdown list on each row. The DDL is populated with a number from 1 - how ever many rows there are.
I have a save button to save the value of each DDL for each row using a simple loop but the problem is that the dropdown never returns the selected value, it seems to return something like the row index of the gridview + 1.
This is an example of how I select the values in the rows:
3
7
4
6
5
2
1
When I do the same, this is how they will save:
2
3
4
5
6
7
1
This is my code from the save, just to let you know I have tried selectedvalue, selectedindex, selecteditem and text, they all do the same.
//save the data
foreach (GridViewRow r in gvOrder.Rows)
{
if (r.RowType == DataControlRowType.DataRow)
{
//get the details from the grid
Label lblED = r.FindControl("lblED") as Label;
DropDownList ddl = r.FindControl("ddlNewO") as DropDownList;
TextBox txt = r.FindControl("txtNewT") as TextBox;
Label ID = r.FindControl("lblID") as Label;
int Order = Convert.ToInt16(ddl.SelectedValue);
string Text = "";
if (txt.Text != "")
{
Text = txt.Text;
}
//save each row to the db
try
{
SqlConnection dbConnection = new SqlConnection();
dbConnection.ConnectionString = GetConnection.GetConnectionString();
SqlCommand dbCommand = new SqlCommand("PL_UserColumns_Save", dbConnection);
dbCommand.CommandType = CommandType.StoredProcedure;
dbCommand.Parameters.Add("#PageID", SqlDbType.Int).Value = Convert.ToInt16(constPageID);
dbCommand.Parameters.Add("#UserID", SqlDbType.Int).Value = Convert.ToInt16(strUserID);
dbCommand.Parameters.Add("#Order", SqlDbType.Int).Value = Convert.ToInt16(Order);
dbCommand.Parameters.Add("#ColumnID", SqlDbType.Int).Value = Convert.ToInt16(ID.Text);
dbCommand.Parameters.Add("#ED", SqlDbType.Int).Value = Convert.ToInt16(lblED.Text);
dbCommand.Parameters.Add("#Text", SqlDbType.NVarChar).Value = "'" + Text + "'";
dbConnection.Open();
dbCommand.ExecuteNonQuery();
dbConnection.Close();
}
catch (SqlException ex)
{
ExceptionHandling.SQLException(ex, constPageID, constIsSiteSpecific);
}
}
}

to get the DropDownList selected value you have to use this:
ddl.SelectedItem.Value

You can check Request.Form to get the posted values. Assuming that your drop-down names will increase with each row e.g. ddlNew0, ddlNew1, etc., then you can do this
var value = Request.Form["ddlNew" + rowIndex];

I would do it in two possible ways:
Add a bit of JavaScript to populate a hidden field and then grab and separate the values in the back-end
Add auto-postback on dropdowns and an onClick method. Also pass the item id as argument. Then do the saving bit in the onclick method.
I would prefer the second one.

Related

How to for each a dataset for each button?

What is the syntax for iterating through a column and changing the values to each button as it iterates?
Example : I have an SQL table with a column named OK with values (0 or 1) and 20 buttons on a form, each button corresponds to a row (button 1 to row 1, button 2 to row 2...etc). I want to iterate through all 20 rows in my dataset and for each row to assign 0 or 1 to its corresponding button (as in button text)
EDIT : I didnt try anything yet cause i dont know exactly how, i know you can iterate through the rows with
Foreach (DataRow drow in table.Rows)
{
foreach(Button X in this.Controls
{
// It was my idea but it clearly doesnt work
}
}
//Sample for MySqlDB
using MySql;
using MySql.Data;
using MySql.Data.MySqlClient;
private List<string> NumberfromDb = new List<string>();
private int SingleValue = -1;
string QueryGetListUsers = "Select <tablename>.<Columname> From <tablename>;";
cmd = new MySqlCommand(Query, m_mySqlConnection);
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
SingleValue = rdr.GetInt32("OK").ToString();
NumberfromDb.Items.Add(SingleValue);
}
Now you have the Value in the List Just pass it in the "For" loop and assign it to the Button
eg:
btn1.Text = NumberfromDb[i].ToString();

DropDownList not working with SqlDataReader

Hi i am trying to get DropDownList to work with SqlDataReader but its not populating the DropDownlist. The TextBox.Text Reader is working though.
Here is the code I am using:
using (SqlConnection con = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString))
{
SqlCommand command =
new SqlCommand("SELECT * FROM [datarep].[dbo].[OrderHeader] WHERE [OrderNumber] = '"+OrderNumber+"'", con);
con.Open();
SqlDataReader read = command.ExecuteReader();
while (read.Read())
{
TextBox2.Text = (read["CreatedDate"].ToString());
TextBox3.Text = (read["CreatedBy"].ToString());
CompanyStored = (read["CustomerID"].ToString());
TextBox7.Text = (read["Store_Number"].ToString());
DropDownList1.DataTextField = (read["Year"].ToString());
DropDownList1.DataBind();
}
read.Close();
}
Assuming your dropdown is already populated with the list of years, you need to set its value rather than setting its DataTextField - that property is meant for defining the column or property name of the data source for text, not setting the selected value itself.
DropDownList1.SelectedValue = read["Year"].ToString();
If you don't have the dropdown even populated yet, then you have to populate it in advance, using a data source, which is probably a list of years. For example, suppose you want all years between 2000 and 2050, something like this might do the trick:
var dataSource = Enumerable.Range(2000, 51)
.Select(x => new { TheYear = x })
.ToArray();
DropDownList1.DataSource = dataSource;
DropDownList1.DataValueField = "TheYear";
DropDownList1.DataTextField = "TheYear";
DropDownList1.DataBind();
Note that the DataTextField and DataValue field represent the property of the object in the data source.
For something simple like numbers, you can populate the dropdown one at a time as well, rather than using a data source - it's the same result in the end.
SqlDataReader reads your data line by line. If you want to use a DataReader you'll have to add a new list item to your DDL per iteration
Try it like this:
while (read.Read())
{
/*code omitted*/
var item = new ListItem();
item.Text = read["Year"].ToString();
item.Value = read["Year"].ToString();
DropDownList1.Items.Add(item);
}
Further reading and alternative solutions:
What is the right way to populate a DropDownList from a database?

Unique DataGridViewComboBox per row working with SelectedIndex error

I managed to get it to work (I believe), however I am noticing an error when switching between the drop downs between rows.
See below for example:
Row 1 drop down contains {A, E, F} Row 2 drop down contains {B, C, D, A}
The displayed value in both rows is A. I use the dropdown in row 1 fine and correctly, then use the dropdown in row 2 fine and correctly. When i go back to the dropdown in row 1 i get an error stating that the index[3] (which is the index of A in row 2) is out of range.
Apparently i cannot post images sub 10 rep, so ill try to recreate the error message exactly.
'
The following exception occurred in DataGridView:
System.ArguementOutOfRangeException: InvalidArguement = Value of '8'
is not a valid for 'SelectedIndex'.
Parameter name: SelectedIndex
at System.Windows.Forms.ComboBox.set_SelectedIndex(Int32 value)
at
System.Windows.Forms.ListControl.DataManager_ItemChanged(Object sender, ItemChangedEventArgs e)
at System.Windows.Forms.ListControl.SetDataConnection(Object newDataSource, BindingMemberInfo newDisplayMember, Booleanforce)
...
..
.
'
I have looked all over and cannot figure this problem out, please see code posted below.
private void assignResourceGrid_CellBeginEdit_1(object sender, DataGridViewCellCancelEventArgs e)
{
if(assignResourceGrid.Columns["rscNameComboBox"].Index == e.ColumnIndex && e.RowIndex != -1)
{
resourceList.Clear();
string currentRowTeam = assignResourceGrid.Rows[e.RowIndex].Cells[assignResourceGrid.Columns["PersistentTeam"].Index].Value.ToString();
string currentRowDept = assignResourceGrid.Rows[e.RowIndex].Cells[assignResourceGrid.Columns["NAME"].Index].Value.ToString();
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
sql = "select distinct rsc.ID, \"ResourceName\" from rsc "
+ "inner join persistentteamassign on rsc.id = persistentteamassign.rsc_id "
+ "where persistentteamassign.persistentteam_id = (select id from persistentteam where teamname = :currentTeam "
+ "AND department_id = (select id from departmentteam where name = :currentDept)) "
+ "AND rsc.\"ResourceName\" is not null";
cmd = new OracleCommand(sql, conn);
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("currentTeam", currentRowTeam);
cmd.Parameters.Add("currentDept", currentRowDept);
dreader = cmd.ExecuteReader();
if (dreader.HasRows == true)
{
while (dreader.Read())
resourceList.Add(new Resource
{
id = Convert.ToInt64((dreader["ID"])),
name = (dreader["ResourceName"].ToString())
});
}
DataGridViewComboBoxCell cell = (DataGridViewComboBoxCell)(assignResourceGrid.Rows[e.RowIndex].Cells[assignResourceGrid.Columns["rscNameComboBox"].Index]);
cell.DataSource = null;
cell.Items.Clear();
cell.DataSource = resourceList;
cell.ValueMember = "name";
cell.DisplayMember = "name";
}
Note:
1. The DataGridView is being databound by an sql query.
2. These 3 columns mentioned in the code are each bound to a column in the database.
3. I am then applying the custom drop downs on a per row basis once a user begins typing the resource name.
The values in rscNameComboBox should be dependant on the combination of items in PersistentTeam & Name columns. All rows will have a common displayed value. This is because a person can be on multiple teams, but the team has different members.
For anyone having a similar problem I found a solution to dynamically binding each row. Whatever the reason I do not receive an error by pulling 'all' of the data into a table then just using rowfilter and binding each cell dynamically based on that filtered table. This is achieved either through type ahead or using the dropdown.
private void assignResourceGrid_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
DataGridViewComboBoxCell cellRscName = (DataGridViewComboBoxCell)(assignResourceGrid.Rows[e.RowIndex].Cells["RscName"]);
if (assignResourceGrid.Columns["RscName"].Index == e.ColumnIndex && e.RowIndex != -1)
{
deptName = assignResourceGrid.Rows[e.RowIndex].Cells["DeptTeamName"].Value.ToString()
teamName = assignResourceGrid.Rows[e.RowIndex].Cells["PersistentTeamName"].Value.ToString()
//show all resources on each team
resourceData.Tables[0].DefaultView.RowFilter = "DepartmentName= '" + deptName+ "' "
+ "and TeamName= '" + teamName + "' ";
cellRscName.DataSource = resourceData.Tables[0];
cellRscName.DisplayMember = "ResourceName";
cellRscName.ValueMember = "ResourceName";
}
}

how to insert data through datagridview after selecting operation in combobox

i have a combobox column in my datagridview in which i have added three items insert,update and delete now i wannt to choose one item and perform corresponding operation.
but when i do this error show input string is not in correct format,may be i am unable to select the exact row relative to that combobox row.will anybody help.
here is code of my combobox SelectedIndexChanged event of datagridview
ComboBox cmb = (ComboBox)sender;
if (cmb.SelectedItem.ToString() == "insert")
{
con = new SqlConnection(#"Data Source=krishna-PC\SQLEXPRESS;Initial Catalog=dbnew;Integrated Security=True");
int a = int.Parse(dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Cells[1].ToString());
string b = dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Cells[2].Value.ToString();
string c = dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Cells[3].Value.ToString();
com = new SqlCommand("insert into mytable values(#a,#b,#c,#d)", con);
com.Parameters.AddWithValue("#a", a);
com.Parameters.AddWithValue("#b", b);
com.Parameters.AddWithValue("#c", c);
com.Parameters.AddWithValue("#d", "govind");
con.Open();
com.ExecuteNonQuery();
MessageBox.Show("Data has been inserted");
}
Just fix the line for Cell 1, You forgot the .Value property:
int a = int.Parse(dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Cells[1].Value.ToString());
Instead of using "Value" Use "Text" .Like..
int a = int.Parse(dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Cells[1].Text.ToString());
string b = dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Cells[2].Text.ToString();
string c = dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].Cells[3].Text.ToString();

Use switch statement inside foreach?

in this scenario I'm dealing with two gridviews (gvSnacks and gvSnackCart). gvSnacks contains a fixed list of items with a template button column to "add" the item to gvSnackCart.
The foreach comes into play because I want to make sure that the item hasn't already been placed in the cart. If the user selects an item twice, I want to execute a sql command and make the gvSnackCart quantity of that item go up by 1 (instead of generating a new record).
If the record isn't in the gvSnackCart, the foreach should loop all the way to its default and insert it.
Here's the sql command to insert
string sqlInsert = "INSERT INTO ShoppingCart…
([shopperID], [itemName], [itemType], [quantityOrdered], [unitPrice])…
VALUES (#shopperID, #itemName, #itemType, #quantityOrdered, #unitPrice)";
myCommand.Parameters.Add("#shopperID", System.Data.SqlDbType.NVarChar).Value = txtCurrentUser.Text;
myCommand.Parameters.Add("#itemName", System.Data.SqlDbType.NVarChar).Value = snackDescription;
myCommand.Parameters.Add("#itemType", System.Data.SqlDbType.NVarChar).Value = "snack";
myCommand.Parameters.Add("#quantityOrdered", System.Data.SqlDbType.Int).Value = 1;
myCommand.Parameters.Add("#unitPrice", System.Data.SqlDbType.Money).Value = snackPrice;`
SqlCommand myCommand = new SqlCommand(sqlInsert, myConnection);`
Now I get the selected item's name from gvSnacks, and compare with each one present inside gvSnackCart
// Retrieve item's name
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow row = gvSnacks.Rows[index];
string snackDescription = row.Cells[2].Text.ToString();
// Checks for duplicate snack listing
int duplicate = 0;
foreach (GridViewRow gvRowSnack in gvSnackCart.Rows)
{
if (gvRowSnack.Cells[1].Text.ToString() == snackDescription)
{
duplicate = 1;
}
switch (duplicate)
{
case 0:
break;
case 1:
//This is the case where it's a duplicate
//and will be a command to update the record
break;
default:
try
{
myConnection.Open();
myCommand.ExecuteNonQuery();
myConnection.Close();
}
catch (Exception ex)
{
lblError.Visible = true;
lblError.Text = "There was an error while adding the records" + "<br />" + ex.Message;
}
break;
}
}
The gvSnackCart is databound and should update with a new item, unless its a duplicate where it'd do an update. For some reason however it is not functioning. I am not getting an error at runtime. I have tested a read/write with a label so I know I'm retrieving the item name from gvSnacks. I'm also checking the database table and it's not showing any records being added. What seems wrong?
You can spare yourself a lot of hassle by using LINQ:
foreach (var snacks in gvSnackCart.Rows.GroupBy(snack => snack.Cells[1].Text.ToString()))
{
var p = myCommand.Parameters;
// I'm largely guessing at these, but hopefully you get the idea.
p.Add("#shopperID" , SqlDbType.NVarChar).Value = txtCurrentUser.Text;
p.Add("#itemName" , SqlDbType.NVarChar).Value = snacks.Key;
p.Add("#itemType" , SqlDbType.NVarChar).Value = /* ??? */;
p.Add("#quantityOrdered", SqlDbType.Int ).Value = snacks.Count();
p.Add("#unitPrice" , SqlDbType.Money ).Value = snacks.Sum(r => r.SnackPrice);
…
}

Categories