Using dt.select to populate dropdown - c#

I'm trying to populate a dropdown with selectedvalues from my database. The reason why I'm using a dt.select is because I don't want to keep calling the stored procedure for every dropdown (I have about 20 dropdowns).
The problem is if there is a value London in Location dropdown and London in Department dropdown, it'll populate in both dropdown. I only want it to populate in Location or in Department. I have a feeling that it could be this part in my code that populating both ddl.
if (ddlLocation.Items[j].Value.ToString() == ds.Tables[0].Rows[i][0].ToString())
I would like to go through the data row and only populate those values.
DataTable dt = new DataTable();
DataSet ds = obj.runSPHere(GUID);
dt = ds.Tables[0];
//Populate the Location Dropdown
DataRow[] Location = dt.Select("Category = 'Location'");
foreach (DataRow row in Location)
{
for (int i = 0; ds.Tables[0].Rows.Count > i; i++)
{
for (int j = 0; ddlLocation.Items.Count > j; j++)
{
if (ddlLocation.Items[j].Value.ToString() == ds.Tables[0].Rows[i][0].ToString())
{
ddlLocation.Items[j].Selected = true;
}
}
}
}
//Populate the Department Dropdown
DataRow[] Department = dt.Select("Category = 'Department'");
foreach (DataRow row in Department)
{
for (int i = 0; ds.Tables[0].Rows.Count > i; i++)
{
for (int j = 0; ddlDepartment.Items.Count > j; j++)
{
if (ddlDepartment.Items[j].Value.ToString() == ds.Tables[0].Rows[i][0].ToString())
{
ddlDepartment.Items[j].Selected = true;
}
}
}
}

Here's how I did it.
Start with a stored procedure that gets the id column and the actual column that you want populating your dropdowns. You'll want a separate SELECT statement for each dropdown:
SELECT id, location
FROM LocationTable
SELECT id, department
FROM DepartmentTable
Then create a method for populating your dropdowns:
private void PopulateDropdowns()
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["name of your connection string"].ConnectionString))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "name of your stored procedure";
// Double check that the connection is open
if (conn.State == ConnectionState.Closed)
conn.Open();
// Create a SqlDataAdapter and fill it with the data from your stored procedure
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
// Since you have so many, I would name the DataSet tables
// These will correspond with each of your SELECT statements
// with 0 being the first SELECT, 1 being the second SELECT and so on
ds.Tables[0].TableName = "Location";
ds.Tables[1].TableName = "Department";
// Then set their DataSources
// and bind each table to its corresponding dropdown
ddlLocation.DataSource = ds.Tables["Location"];
ddlLocation.DataValueField = "id";
ddlLocation.DataTextField = "location";
ddlLocation.DataBind();
ddlDepartment.DataSource = ds.Tables["Department"];
ddlDepartment.DataValueField = "id";
ddlDepartment.DataTextField = "department";
ddlDepartment.DataBind();
}
}
}
And if you'd like the default option in your drop down to say something other than whatever comes first from your SELECT statements, you can set a property called AppendDataBoundItems to true. Then manually add a ListItem to your drop down, set its Text to whatever you like and set its Value to -1 (to get it to float to the top):
<asp:DropDownList runat="server" ID="ddlLocation" AppendDataBoundItems="true">
<asp:ListItem Enabled="true" Text="Please Select" Value="-1"></asp:ListItem>
</asp:DropDownList>
Then I put PopulateDropdowns(); in my page load. It runs the stored procedure once and all the dropdowns on the page are populated.

You can use DataView to separate your results like this way :
var locationView = new DataView(dt)
{
RowFilter = "Category = 'Location'"
};
foreach (DataRowView rowView in locationView)
{
DataRow row = rowView.Row;
for (int j = 0; ddlLocation.Items.Count > j; j++)
{
if (ddlLocation.Items[j].Value.ToString() == row[0].ToString())
{
ddlLocation.Items[j].Selected = true;
}
}
}
so you can create two views one for location and another for department one time and use them whenever you need them.
I noticed that you're looping in your filtered rows then inside it looping through all your table rows. and I think this is what makes your code not functioning as you wish. I hope I helped you

Related

How to fetch values from database in pivot while working with dynamic controls in asp.net c#

I'm Prateek, trying to create an application that takes user inputs from the controls that are being generated dynamically such as a TextBox or a DropDownList.
These controls are generated from the database values itself i.e., I'm storing all the values that are to be created in a table named 'usertasks'.
Now, everything is working fine and controls are dynamically generated, the user inputs are stored in another table named 'taskEntries'. The problem I'm facing is with the values being fetched:
The above image is of a table to save what kind of controls the user wants to create and their labels.
Another image to show how data is being stored right now:
How I want the data to be fetched:
Kindly let me know how do I do it in asp.net c#.
What I tried?
//Below code to get all data into a DataTable
protected void getData()
{
using (SqlConnection con = new SqlConnection(ConnectionManager.ConString))
{
con.Open();
using (SqlDataAdapter sda = new SqlDataAdapter("select (cdate + ', ' + ctime) as 'Date', taskID as 'Task ID', deptID as 'Department ID', empID as 'Employee ID', question as 'Question', userInput as 'Input' from taskEntries", con))
{
DataTable dt = new DataTable();
sda.Fill(dt);
ViewState["dt"] = dt;
BindGrid(dt, false);
}
con.Close();
}
ConvertRowsToColumns();
}
//Below code to bind the gridview
private void BindGrid(DataTable dt, bool rotate)
{
grdUserData.ShowHeader = !rotate;
grdUserData.DataSource = dt;
grdUserData.DataBind();
if (rotate)
{
foreach (GridViewRow row in grdUserData.Rows)
{
row.Cells[0].CssClass = "header";
}
}
}
//Below code to convert the rows to columns
private void ConvertRowsToColumns()
{
DataTable dt = (DataTable)ViewState["dt"];
DataTable dt2 = new DataTable();
for (int i = 0; i <= dt.Rows.Count; i++)
{
String Question = Convert.ToString(dt.Rows[i]["question"]);
String InputType = Convert.ToString(dt.Rows[i]["inputType"]);
dt2.Columns.Add(Question);
dt2.Columns.Add(InputType);
}
for (int i = 0; i < dt.Columns.Count; i++)
{
dt2.Rows.Add();
dt2.Rows[i][0] = dt.Columns[i].ColumnName;
}
for (int i = 0; i < dt.Columns.Count; i++)
{
for (int j = 0; j < dt.Rows.Count; j++)
{
dt2.Rows[i][j + 1] = dt.Rows[j][i];
}
}
BindGrid(dt2, true);
}

Display selected columns vertically

I have a table named orders.
I want to display Order Date, Sum of the product quantity ordered and the product_name.
Here is the data I want to display:
Data to Display
As above, I want product names to be displayed horizontally, with the sum of the product orders displayed vertically by date.
I am using C# and an MS Access database.
I am able to display the data in gridview row-wise. Here is the code:
private void btn_all_orders_Click(object sender, EventArgs e)
{
try
{
connection.open
OleDbCommand command = new OleDbcommand();
command.connection = connection;
string query = "select order_date as 'Order Date', product_name as
'Items', Sum(order_quantity) as 'No of Orders' from order where cust_id =
'" + txt_cust_id.Text + "' group by order_date, product_name";
command.commandText = query;
OleDbDataAdapter da = new OleDbDataAdapter(command);
DataTable dt = new DataTable();
da.Fill(dt);
datagridview.DataSource = dt;
connectionn.Close();
}
catch (Exception ex)
{
Messagebox.Show("Error " + ex);
connection.Close();
}
}
How do I change this to achieve the goal described above?
I think you are asking for is this:
What you will need to do is ADD a Column to your to your datatable.
Then add an expression to that column it.
da.Fill(dt);
dt.Columns.Add("TOTAL");
dt.Columns("Total").Expression = "Count(Product1) + Count(Product2) + Count(Product3)";
datagridview.DataSource = dt;
connectionn.Close();
The totals on the bottom are coming from your SelectQuery => Sum(order_quantity). You can modify the query to get rid of that.
Some info
Of course the query could be changed so that it returns a computed column back and then you do not need to do it in the datatable.
Actual SQL for changing the query so that it returns a computed column back - https://stackoverflow.com/questions/3932205/to-calculate-sum-two-alias-named-columns-in-sql
The code above is pseudo - untested code - so please read the links.
EDIT
You could also look here : Display Data Vertically in the DataGridview
Too much code to post but basically the real work is done by flipping the dataset - as Mr. Gamal did.
public DataSet FlipDataSet(DataSet my_DataSet)
{
DataSet ds = new DataSet();
foreach (DataTable dt in my_DataSet.Tables)
{
DataTable table = new DataTable();
for (int i = 0; i <= dt.Rows.Count; i++)
{ table.Columns.Add(Convert.ToString(i)); }
DataRow r;
for (int k = 0; k < dt.Columns.Count; k++)
{
r = table.NewRow();
r[0] = dt.Columns[k].ToString();
for (int j = 1; j <= dt.Rows.Count; j++)
{ r[j] = dt.Rows[j - 1][k]; }
table.Rows.Add(r);
}
ds.Tables.Add(table);
}
return ds;
}

Generate labels and checkboxes in Visual Studio for each row in a db query

I want to have a label and checkbox for each row in from my query.
I needed to get the number of records from my sql query, but I read that SELECT statements will not work with int numberOfRecords = sqlCmd2.ExecuteNonQuery();. So what should I do instead to get the number of records selected from my query (see code below)?
Is this code enough to do what I need to generate labels and checkboxes from a db? Or am I missing something?
Side Note: I do not want to use the Repeater Control. I have tried it, and it isn't robust enough as I program more complicated pages.
ASP
<table>
<tr>
<td>
<asp:Label ID="LabelFormFields" runat="server" Text="Label"></asp:Label>
</td>
<td>
<asp:CheckBoxList ID="CheckBoxListFormFields" runat="server">
</asp:CheckBoxList>
</td>
</tr>
</table>
C#
protected void Page_Load(object sender, EventArgs e)
{
using (SqlConnection sqlConn2 = new SqlConnection(ConfigurationManager.ConnectionStrings["Events2"].ConnectionString))
{
sqlConn2.Open();
using (SqlCommand sqlCmd2 = new SqlCommand())
{
sqlCmd2.Connection = sqlConn2;
sqlCmd2.CommandType = System.Data.CommandType.Text;
sqlCmd2.CommandText = string.Format("SELECT DisplayName FROM FormField WHERE EventId = 1 AND Visible = 0 ORDER BY ColumnOrder ASC;");
sqlCmd2.ExecuteNonQuery();
int numberOfRecords = //something here;
using (SqlDataReader sqlReader = sqlCmd2.ExecuteReader())
{
while (sqlReader.Read())
{
for (int i = 0; i < numberOfRecords; i++)
{
var PanelFormFields = new Panel();
var LabelFormFields = new Label();
var ListItemFormFields = new ListItem();
LabelFormFields.Text = sqlReader["DisplayName"].ToString();
CheckBoxListFormFields.Items.Add(new ListItem(sqlReader["DisplayName"].ToString(), "C"));
PanelFormFields.Controls.Add(LabelFormFields);
PanelFormFields.Controls.Add(CheckBoxListFormFields);
}
}
}
sqlConn2.Close();
}
}
}
int numberOfRecords = sqlCmd2.ExecuteNonQuery(); //you will get the record numbers; https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executenonquery.aspx
But you don't need the numbers here.
your while (sqlReader.Read()) will help to to control the bounds of loop. Based on your description, you don't need this reader. just fill a datatable, then assign it to a datagrid control. as per you want to display a checkbox for each line, you need to make a custom column.
Here is a good sample about how to implement a checkbox and a label in datagrid: http://www.codeproject.com/Articles/7629/Using-CheckBoxes-within-the-DataGrid-control-to-se
use DataTable.Load(IDataReader reader) method to fill a DataTable and then use DataTable.Rows.Count to get number of Records. change your code to something like this:
.
.
sqlCmd2.CommandType = System.Data.CommandType.Text;
sqlCmd2.CommandText = string.Format("SELECT DisplayName FROM FormField WHERE EventId = 1 AND Visible = 0 ORDER BY ColumnOrder ASC;");
int numberOfRecords;
using (System.Data.DataTable dataTable =new System.Data.DataTable())
{
dataTable.Load(sqlCmd2.ExecuteReader());
numberOfRecords = dataTable.Rows.Count;
for (int i = 0; i < dataTable.Rows.Count; i++)
{
System.Data.DataRow dr = dataTable.Rows[i];
var PanelFormFields = new Panel();
var LabelFormFields = new Label();
var ListItemFormFields = new ListItem();
LabelFormFields.Text = dr["DisplayName"].ToString();
CheckBoxListFormFields.Items.Add(new ListItem(dr["DisplayName"].ToString(), "C"));
PanelFormFields.Controls.Add(LabelFormFields);
PanelFormFields.Controls.Add(CheckBoxListFormFields);
}
}
Here is one answer. Please note that I put the code in the Page_Init rather than Page_Load because the Page_Load reloads with every postback and any changes that were not yet written to the database could go away.
protected void Page_Init(object sender, EventArgs e)
{
DataTable dt = GetData();
//int numberOfRecords = dt.Rows.Count;
foreach (DataRow row in dt.Rows)
{
var PanelFormFields = new Panel();
var LabelFormFields = new Label();
var ListItemFormFields = new ListItem();
LabelFormFields.Text = row[0].ToString();
CheckBoxListFormFields.Items.Add(new ListItem(row[0].ToString(), "C"));
PanelFormFields.Controls.Add(LabelFormFields);
PanelFormFields.Controls.Add(CheckBoxListFormFields);
}
}
private DataTable GetData()
{
DataTable dt = new DataTable();
using (SqlConnection sqlConn2 = new SqlConnection(ConfigurationManager.ConnectionStrings["Events2"].ConnectionString))
{
sqlConn2.Open();
string sql = string.Format("SELECT DisplayName FROM FormField WHERE EventId = 1 AND Visible = 0 ORDER BY ColumnOrder ASC;");
using (SqlCommand sqlCmd2 = new SqlCommand(sql, sqlConn2))
{
using (SqlDataAdapter da = new SqlDataAdapter(sqlCmd2))
{
da.Fill(dt);
}
}
}
return dt;
}
Also note that I refactored to use a GetData() method to retrieve the DataTable object and simplify the Page_Init method. I did not close the sqlConn2 object because the using block does this for me. I also used a DataAdapter because it is a simple, fast way to fill a table. Finally, while I kept the numberOfRecords in a commented line to show you how you can get the count, if you need it, it is commented because the foreach loop doesn't need this value.

Inserting data into gridView without using SqlDataSource and DataBind from a Sql Table

In my database web application, I am trying to add data to a column in gridView from a SQL table using the following code snippet
public void GetRowHeaders(GridView gridViewSample)
{
string commandstr = #"SELECT ID FROM WhiteBoardTest WHERE ID!=0 ORDER BY ID";
SqlCommand rowHeaderCmd = new SqlCommand(commandstr, sqlcon);
sqlcon.Open();
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = rowHeaderCmd;
da.Fill(dt);
for (int i = 0; i < dt.Columns.Count; i++)
{
for (int j = 0; j < dt.Rows.Count; j++)
{
gridViewSample.Rows[0].Cells[j].Text = dt.Rows[j][i].ToString();
}
}
sqlcon.Close();
}
When I ran the above code, I got the error saying
ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection
I understand that the exception has occurred because the gridView has no rows or columns available.
Can anyone suggest me how to add rows to a column and also I am not using SqlDataSource because I would like add one more column to the gridView from a different table.
I would just include the extra column in your select statement and just bind to the gridview - unless there's a specific reason for not doing that. note the new sql!
public void GetRowHeaders(GridView gridViewSample)
{
string commandstr = #"SELECT a.*, b.somecolumn FROM tablea as a inner join tableb as b on b.someid= a.someid WHERE ID!=0 ORDER BY ID";
SqlCommand rowHeaderCmd = new SqlCommand(commandstr, sqlcon);
sqlcon.Open();
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = rowHeaderCmd;
da.Fill(dt);
gridViewSample.DataSource = dt;
gridviewSample.DataBind();
sqlcon.Close();
}
Or you could populate a collection of some class ( remember to use properties for gridviews databind), a List maybe, and just databind that to the grid.
Dayakar, what you can do is add additional column and data to DataTable itself and then bind it to the gridview. below is a example code.
private void SetupGridView()
{
var dt = GetDataTable();
// add addition column
dt.Columns.Add(new DataColumn() {ColumnName = "Id2", DataType = typeof (int)});
// add additional data
for (var i = 0; i < dt.Rows.Count; i++)
{
dt.Rows[i]["Id2"] = Convert.ToInt32(dt.Rows[i][0])*2;
}
GridView1.DataSource = dt;
GridView1.DataBind();
}
You can also merge two datatables to create one datatable and then bind it to gridview. Refer http://msdn.microsoft.com/en-us/library/fk68ew7b.aspx

Populate dropdownlist inside a gridview

I have a Dropdownlist in a Gridview and i have to show the records associated with every id.And the ID contains more than 10 records so how can i show them??
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
con.Open();
var ddl = (DropDownList)e.Row.FindControl("DropDownList1");
//int CountryId = Convert.ToInt32(e.Row.Cells[0].Text);
SqlCommand cmd = new SqlCommand("select LastName from Profile_Master", con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
con.Close();
ddl.DataSource = ds;
ddl.DataTextField = "LastName";
ddl.DataBind();
}
}
FillSelect(myDropDownList, "--select--", "0", true);
public static void FillSelect(DropDownList DropDown, string SelectItemText, string SelectItemValue, bool includeselectitem)
{
List<PhoneContact> obj_PhoneContactlist = getAll();
if (obj_PhoneContactlist != null && obj_PhoneContactlist.Count > 0)
{
DropDown.DataTextField = "PhoneContactName";
DropDown.DataValueField = "id";
DropDown.DataSource = obj_PhoneContactlist.OrderBy(o => o.PhoneContactName);//linq statement
DropDown.DataBind();
if (includeselectitem)
DropDown.Items.Insert(0, new ListItem(SelectItemText, SelectItemValue));
}
}
public static List<PhoneContact> getAll()
{
obj_PhoneContactlist = new List<PhoneContact>();
string QueryString;
QueryString = System.Configuration.ConfigurationManager.ConnectionStrings["Admin_raghuConnectionString1"].ToString();
obj_SqlConnection = new SqlConnection(QueryString);
obj_SqlCommand = new SqlCommand("spS_GetMyContacts");
obj_SqlCommand.CommandType = CommandType.StoredProcedure;
obj_SqlConnection.Open();
obj_SqlCommand.Connection = obj_SqlConnection;
SqlDataReader obj_result = null;
obj_SqlCommand.CommandText = "spS_GetMyContacts";
obj_result = obj_SqlCommand.ExecuteReader();
//here read the individual objects first and append them to the listobject so this we get all the rows in one list object
using (obj_result)
{
while (obj_result.Read())
{
obj_PhoneContact = new PhoneContact();
obj_PhoneContact.PhoneContactName = Convert.ToString(obj_result["PhoneContactName"]).TrimEnd();
obj_PhoneContact.PhoneContactNumber = Convert.ToInt64(obj_result["PhoneContactNumber"]);
obj_PhoneContact.id = Convert.ToInt64(obj_result["id"]);
obj_PhoneContactlist.Add(obj_PhoneContact);
}
}
return obj_PhoneContactlist;
}
I have done this to get my phonecontacts which are in the data base into dropdown you can change the stored procedures and the values according to your need.
Hope this helps:D
We just ran into this issue where I work. Our way around this problem was to first get the DropDownLists UniqueID. This is basically a Client ID. Inside of that ID is a reference to the row of the GridView that it was selected from. THE ONLY PROBLEM is that it seems to add 2 to the row count. So if you select Row 1's DropdownList, the Unique ID will bring you a reference to the 3rd row. So:
Get the unique ID > Split it however you need to to get the row > use the row number to get the values you need.

Categories

Resources