how to get values in dropdownlist bounded within a gridview? - c#

Inside gridview a dropdownlist is there
<asp:TemplateField HeaderText="Quantity">
<ItemTemplate>
<asp:DropDownList ID="quantity" runat="server" DataValueField="ItemID" DataTextField="Quantity">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
for each itemid there is some numeric value in Quantity field of Database Table
i want that this dropdown must contain the values from 1 to quantity.DataTextField for all the items present in the cart
the procedure by which gridview is bound is
create proc [dbo].[prcItemsinCart](#CartID int)
as
select distinct ct.Price,ct.Quantity,ct.ItemID,
ct.CartID,ct.ProductID,p.ProductName,
isnull(( select top 1 convert(varchar,PhotoID,10) + '.' + ExtName
from ProductPhoto
where ProductID = ct.ProductID ),'NoImage.jpg'
) as Product,
( Select Price*Quantity
from CartItems
where CartID=ct.CartID and ProductID=ct.ProductID
) as SubTotal
from CartItems as ct
inner join ProductInfo as p on ct.ProductID=p.ProductID
inner join ProductPhoto as pp on ct.ProductID=pp.ProductID
where ct.CartID=#CartID

I would add a HiddenField in the TemplateField to hold the CartID, I will use the CartID in the code. My Markup should look like:
<asp:TemplateField HeaderText="Quantity">
<ItemTemplate>
<asp:HiddenField ID="hdnId" runat="server" value='<%#Eval("CartID") %>'></asp:HiddenField>
<asp:DropDownList ID="quantity" runat="server" DataValueField="ItemID" DataTextField="Quantity">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
In the code, in GridView's RowDataBound I am finding the DropDownList and HiddenField, running a Sql Query to bring my expected data, and binding them to my DropdownList:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList quantity = e.Row.FindControl("quantity") as DropDownList;
HiddenField hdnId = e.Row.FindControl("hdnId") as HiddenField;
if (quantity != null && hdnId != null)
{
string queryString = String.Format("SELECT ItemID, Quantity FROM CartItems WHERE CartID= {0}", hdnId.Value);
//MyConnectionString is your connection string in web.config
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ToString()))
{
SqlCommand command = new SqlCommand(queryString, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
quantity.DataSource = reader;
quantity.DataValueField = "ItemID";
quantity.DataTextField = "Quantity";
quantity.DataBind();
}
}
}
}

Related

Split a Gridview in two Grids in c#.net

I have a GridView which gets the data from a SQL Server database.
The GridView binds when the user select the date from an CalendarExtender, because the data is different one day to another, also the rows quantity.
E. G., in Saturdays the GridView is filled with 18 rows. In Tuesdays, with 58.
Concern:
What I need to do is to split the GridView in 2 parts (2 GridViews). E. G., In tuesdays, 29 rows each GridView, in saturdays, 9 rows each.
I have tried:
To bring the daily data into a GridView, called "GVTotal":
if (Weekday.Value == "Saturday")
{
GVTotal.DataSourceID = SaturdayData.ID;
GVTotal.DataBind();
}
To count the rows from GVTotal, and divide by 2.
int everything = GVTotal.Rows.Count;
int half = everything / 2;
What I want to do now, is to "Copy" the rows from 0 to half to GVPart1, and from half to everything to GVPart2, in the exactly same order than in GVTotal.
I have read that maybe using a DataTable will made this possible.
I am not pretty sure how to do that. Could someone help me please?
You could have a Repeater with two items, one for each GridView. In the example below, the Repeater is rendered as a table with a single row. Each GridView is in a cell of that row, with an empty cell between them.
<asp:Repeater ID="repeater1" runat="server" OnItemDataBound="repeater1_ItemDataBound">
<HeaderTemplate>
<table cellspacing="0" cellpadding="0">
<tr>
</HeaderTemplate>
<ItemTemplate>
<td>
<asp:GridView ID="gvHalf" runat="server" >
...
</asp:GridView>
</td>
</ItemTemplate>
<SeparatorTemplate>
<td style="width: 32px;" />
</SeparatorTemplate>
<FooterTemplate>
</tr>
</table>
</FooterTemplate>
</asp:Repeater>
In order to get the two data sources, you declare two DataTables in your class:
private DataTable dtTopHalf;
private DataTable dtBottomHalf;
In Page_Load, the two DataTables are populated by splitting the full DataTable in two parts, and the data source of the Repeater is set to two boolean values:
void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
using (SqlConnection conn = new SqlConnection("Data Source=(local); Integrated Security = True; Initial Catalog=TestMP"))
using (SqlCommand cmd = new SqlCommand("SELECT * FROM Clients ORDER BY ClientID ASC", conn))
{
cmd.CommandType = CommandType.Text;
SqlDataAdapter dataAdapter = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
dataAdapter.Fill(dt);
int halfCount = dt.Rows.Count / 2;
dtTopHalf = dt.AsEnumerable().Select(x => x).Take(halfCount).CopyToDataTable();
dtBottomHalf = dt.AsEnumerable().Select(x => x).Skip(halfCount).CopyToDataTable();
}
// Each value in the Repeater indicates if it is the top half or not
repeater1.DataSource = new List<bool>() { true, false };
repeater1.DataBind();
}
}
The specific data source can then be set for each GridView in the ItemDataBound event handler of the Repeater:
protected void repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
bool isTopHalf = (bool)e.Item.DataItem;
GridView gvHalf = e.Item.FindControl("gvHalf") as GridView;
gvHalf.DataSource = isTopHalf ? dtTopHalf : dtBottomHalf;
gvHalf.DataBind();
}
}
Note 1: The Repeater allows to share the same markup for both GridViews. If you prefer, you can declare two separate GridViews in the markup and apply the specific data source to each one in Page_Load.
Note 2: You need a reference to System.Data.DataSetExtensions in your project to use some of the LINQ methods mentioned above.
Thanks to ConnorsFan for the assistance. His answer is the right way to do what I wanted.
As I need to select the date before the data comes in, I wrote Connor's code into my date Textbox OnTextChanged event, into the if (Weekday.Value == "<day of the week>") statement.
This is the solution:
ASPX:
Updated: Only with one GridView, as reccomended:
<asp:Repeater ID="repeater1" runat="server" OnItemDataBound="repeater1_ItemDataBound">
<HeaderTemplate>
<table cellspacing="200px" cellpadding="0">
<tr style="vertical-align: top;">
</HeaderTemplate>
<ItemTemplate>
<td>
<asp:GridView ID="gvHalf" runat="server" BackColor="White" AutoGenerateColumns="False" HeaderStyle-CssClass="tituloshandoff" RowStyle-CssClass="contenidohandoffbatch">
<Columns>
<asp:BoundField HeaderText="IDBATCH" DataField="IDBatch" SortExpression="IDBatch" HeaderStyle-CssClass="TituloInvisible" ItemStyle-CssClass="TituloInvisible" />
<asp:BoundField HeaderText="BATCH" DataField="Nombre" SortExpression="Nombre" />
<asp:BoundField HeaderText="DEALER" DataField="DealerCodigo" SortExpression="DealerCodigo" />
<asp:BoundField HeaderText="CT TIME" DataField="CTStart" SortExpression="CTStart" />
<asp:BoundField HeaderText="STATUS" DataField="Estado" SortExpression="Estado" />
<asp:TemplateField HeaderText="CONTROL">
<ItemTemplate>
<asp:Button ID="Button1" CssClass="botongrid" runat="server" Text="Select" Width="100px" /></ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</td>
</ItemTemplate>
<SeparatorTemplate>
<td style="width: 100px;" />
</SeparatorTemplate>
<FooterTemplate>
</tr>
</table>
</FooterTemplate>
</asp:Repeater>
C#:
I will show only one day in example:
string LaConexion = #"<My Connection String>";
private DataTable dtTopHalf;
private DataTable dtBottomHalf;
protected void TextDate_TextChanged(object sender, EventArgs e)
{
if (diasemana.Value == "Monday")
{
using (SqlConnection conexion = new SqlConnection(LaConexion))
using (SqlCommand comando = new SqlCommand("SELECT [1Monday].IDBatch, Batch.Nombre, Dealer.DealerCodigo, Batch.CTStart, BatchDatos.Estado FROM [1Monday] INNER JOIN Batch ON [1Monday].IDBatch = Batch.IDBatch INNER JOIN Dealer ON Batch.IDDealer = Dealer.IDDealer LEFT OUTER JOIN BatchDatos ON [1Monday].ID = BatchDatos.ID ORDER BY Batch.CTStart", conexion))
{
comando.CommandType = CommandType.Text;
SqlDataAdapter dataAdapter = new SqlDataAdapter(comando);
DataTable dt = new DataTable();
dataAdapter.Fill(dt);
int halfCount = dt.Rows.Count / 2;
dtTopHalf = dt.AsEnumerable().Select(x => x).Take(halfCount).CopyToDataTable();
dtBottomHalf = dt.AsEnumerable().Select(x => x).Skip(halfCount).CopyToDataTable();
}
// Each value in the Repeater indicates if it is the top half or not
repeater1.DataSource = new List<bool>() { true, false };
repeater1.DataBind();
}
}
A Picture:

Store checked checkbox in gridview in database ASP.NET C#

I am able to retrieve out data from database to show which is Y and N using checkbox in gridview. However now i want to to able to store which checkbox is checked back into the database after editing.
What i did so far:
.aspx
<asp:GridView ID="SiteGridView" runat="server" CssClass="datagrid"
GridLines="Vertical" AutoGenerateColumns="False"
Width="100%"
AllowPaging="True" AllowSorting="True"
DataKeyNames="promoID" OnRowCommand="GvPage_RowCommand"
OnPageIndexChanging="GvPage_PageIndexChanging"
OnSorting="GvPage_Sorting"
OnRowDatabound="SiteGridView_RowDataBound"
OnRowEditing="SiteGridView_RowEditing">
<Columns>
<asp:TemplateField HeaderText="Default">
<ItemTemplate>
<asp:CheckBox ID="process_flag" runat="server"
Checked='<%# bool.Parse(Eval("PROCESSED").ToString()) %>'
Enable='<%# !bool.Parse(Eval("PROCESSED").ToString()) %>' />
</ItemTemplate>
<ItemStyle Width="20%" />
</asp:TemplateField>
</Columns>
</asp:GridView>
CodeBehind:
SqlCommand cmd = new SqlCommand("SELECT * , CAST(CASE defaults WHEN 'Y' THEN 1 ELSE 0 END AS BIT) AS PROCESSED FROM Promotions");
SqlDataAdapter da = new SqlDataAdapter();
DataTable dt = new DataTable();
da.SelectCommand = cmd;
// Save results of select statement into a datatable
da.Fill(dt);
SiteGridView.DataSource = dt;
SiteGridView.DataBind();
protected void SiteGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//check userrole & display accrodingly
if (Session["ROLE"].ToString() != "SA")
{
//ImageButton btnEdit = (ImageButton)e.Row.FindControl("btnDelete");
//btnEdit.Visible = false;
SiteGridView.Columns[4].Visible = false;
}
}
}
Have you tried:
Checked='<%# Eval("PROCESSED")%>'
If so, what error messages have you gotten?
For some reason Checkboxes do not trigger GridView RowCommand events. It probably can be done with appropriate calls to ClientScript.GetPostBackEventReference(), but thats a whole other level of complexity. So, in order to act on a CheckBox click and handle events individually:
(NB: I've stripped out much of your coding to clarify my points.)
In your CheckBox set AutoPostBack="true"
Add a handler for OnCheckedChanged.
Make sure the DataKey contains the pk of the row you need to update with the CheckBox State
// Simplified version of your markup
<asp:GridView ID="SiteGridView" runat="server"
DataKeyNames="promoID"
OnRowDataBound="SiteGridView_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="Default">
<ItemTemplate>
<asp:CheckBox ID="process_flag" runat="server"
Checked='<%# bool.Parse(Eval("PROCESSED").ToString()) %>'
Enable='<%# !bool.Parse(Eval("PROCESSED").ToString()) %>'
OnCheckedChanged="process_flag_CheckedChanged" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
In the RowDataBound event, find the CheckBox and add the Row Index as an attribute
// Merge this with your `RowDataBound` event
protected void SiteGridView_RowDataBound( object sender, GridViewRowEventArgs e ) {
if ( e.Row.RowType == DataControlRowType.DataRow ) {
CheckBox cbx = ( CheckBox ) e.Row.FindControl( "CheckBox1" );
cbx.Attributes[ "data-row-idx" ] = e.Row.RowIndex.ToString();
}
}
Handle the CheckChanged event:
// Add this handler to your code
protected void process_flag_CheckedChanged( object sender, EventArgs e )
{
CheckBox cbx = ( CheckBox ) sender;
Int32 rowidx = Convert.ToInt32(cbx.Attributes["data-row-idx"]);
Int32 pk = (Int32) GridView4.DataKeys[rowidx].Value;
// simple way to see event arguments before actually touching the database
GridView4.Caption = string.Format(
"CheckChanged: Row {0}, State: {1}, RowPK: {2} ", rowidx , (cbx.Checked ? "Checked" : "Unchecked"), pk );
// Save Data and rebind the gridview to reflect changes
// Verify your parameters before attempting an actual update
// YourDatabaseCallWithAppropriateParamaters( ... );
GridView1.DataBind();
}
First of all use a foreach loop to findout which rows are checked. Then store ID of those rows in a List.
foreach (GridViewRow row in SiteGridView.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
CheckBox chkRow = (row.Cells[0].FindControl("process_flag") as CheckBox);
if (chkRow.Checked)
{
string ID = row.Cells[columnID].Text;

Fetch MySQL multiple row data and show in individual text box

I am trying to get the StudentFirstName from data base and show in the text box right now am using grid view where it shows the data but not in textbox am not sure how to get all the data from data base and show in individual text box.
MyDB
StudentFirstName SchoolID StudCourse
abc sc123 A
cef sc155 A
gij sc133 A
abc sc122 B
cef sc156 B
gij sc144 B
C#
using (MySqlConnection myConnection = new MySqlConnection(constr))
{
string oString = "Select StudentFirstName from student WHERE StudCourse=#DDSelected_Class order by StudentFirstName ASC";
MySqlCommand oCmd = new MySqlCommand(oString, myConnection);
oCmd.Parameters.AddWithValue("#DDSelected_Class", DDSelected_Class);
myConnection.Open();
using (MySqlDataReader oReader = oCmd.ExecuteReader())
{
if (oReader == null || !oReader.HasRows)
{
ScriptManager.RegisterStartupScript(this, typeof(Page), "alert", "alert('No Student Found')", true);
}
else
{
while (oReader.Read())
{
GridView1.DataSource = oReader;
GridView1.DataBind();
}
}
myConnection.Close();
}
}
Gridview
<asp:GridView ID="GridView1" runat="server"></asp:GridView>
You will need to define ItemTemplate for your column. It will contain a textbox and the field name name in Eval to bind it.
Complete code sample:
<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:TemplateField HeaderText="Names">
<ItemTemplate>
<asp:TextBox ID="txtName" runat="server" Text='<%# Eval("StudentFirstName ") %>' ></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<Columns>
</asp:GridView>

FindControl returns NULL in GridView

I am trying to manipulate a DropDownList, which is in a field of a GridView, from code-behind in ASP.NET. I am doing this by adding the reference to a local DDL with the FindControl method. However, it doesn't seem to work, I have tried multiple approaches (Load, Init Events) but I always get a NullReferenceException.
Here is my code:
<asp:TemplateField HeaderText="Zuständige Führungskraft">
<ItemTemplate>
<!-- <%# Eval("ZustaendigeFuehrungskraft")%> -->
<asp:DropDownList AppendDataBoundItems="true" Enabled="false" runat="server" ID="ddwnFK" >
</asp:DropDownList>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList AppendDataBoundItems="true" runat="server" ID="ddwnFK" >
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
protected void grdBenutzer_RowEditing(object sender, GridViewEditEventArgs e)
{
SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ToString());
conn.Open();
SqlCommand cmd = new SqlCommand("SELECT Nachname, Vorname FROM Benutzer WHERE Benutzerart='Führungskraft' AND Archiviert != 1", conn);
SqlDataReader dr = cmd.ExecuteReader();
DataTable table = new DataTable();
table.Load(dr);
foreach (GridViewRow row in grdBenutzer.Rows)
{
DropDownList ddwnFK = (DropDownList)row.FindControl("ddwnFK");
//if (ddwnFK == null)
// continue;
ddwnFK.Items.Add("keine");
foreach (DataRow dtRow in table.Rows)
{
ddwnFK.Items.Add(dtRow["Nachname"].ToString() + ", " + dtRow["Vorname"].ToString());
}
}
}
can you try access it as
DropDownList ddwnFK = (DropDownList)row.Cells[0].Controls[0];
or see in the Quick watch what are the contents of row there.
It seems you're trying to find your drop down in every row of your grid (even header/footer row doesn't contain your drop down).
You can access the row being edited by using GridViewEditEventArgs.NewEditIndex property:
var row = grdBenutzer.Rows[e.NewEditIndex];
var ddwnFK = (DropDownList)row.FindControl("ddwnFK");

checkboxlist databinding to an entity framework table

I have placed a checkboxlist in a formview object.
I would like to store and load the results of the checkboxlist in a table of an entity framework.
I filled the cbl with values and labels coming from a table that has 2 columns, using the DataSourceID, DataTextField and DataValueField attributes but I can't seem to find how to bind the cbl to the entity framework object in order to store the checked values when the formview is in "EDIT" mode.
Any help would be appreciate. Thanks!
<asp:FormView ID="formView1" runat="server" DataSourceID="Ods1"
Height="203px" Width="495px"
onpageindexchanging="formView1_PageIndexChanging">
<EditItemTemplate>
<asp:CheckBoxList ID="cblProducts" runat="server" RepeatColumns="3"
Width="782px" DataSourceID="SqlDataSource1" DataTextField="ProductName"
DataValueField="ProductCode">
</asp:CheckBoxList>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:ApplicationServices %>"
SelectCommand="SELECT [ProductCode], [ProductName] FROM [Products]">
</asp:SqlDataSource>
</EditItemTemplate>
</asp:FormView>
<asp:ObjectDataSource ID="Ods1" runat="server"
DataObjectTypeName="WebApplication1.EDM.Emp" DeleteMethod="DeleteEmp"
InsertMethod="CreateNewEmp" OldValuesParameterFormatString="original_{0}"
SelectMethod="GetEmpByEmpId" TypeName="WebApplication1.EDM.EmpLogic"
UpdateMethod="UpdateEmp" OnSelecting="Ods1_Selecting">
<SelectParameters>
<asp:RouteParameter Name="EmpId" RouteKey="EmpId" Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
<asp:FormView ID="formView1" runat="server"
OnItemUpdating="formView1_ItemUpdating" ...>
protected void formView1_ItemUpdating(object sender, FormViewUpdateEventArgs e)
{
var cblProducts = formView1.FindControl("cblProducts") as CheckBoxList;
foreach (ListItem item in cblProducts.Items)
{
if (item.Selected)
{
// Check if item.Value is not in the db for this employee, if so add it
}
else
{
// Check if item.Value is in the db for this employee, if so delete it
}
}
// save
}
You need to do the following;
foreach (ListItem chk in cblProducts.Items)
{
string productId= chk.Value;
if (IsProductAvailable(productId) // this method will basically goes to database and return true of false
chk.Selected = true;
else
chk.Selected = false;
}
private void IsProductAvailable(string productId)
{
string query = "SELECT [ProductId] FROM [Product] ";
query += "WHERE [ProductId] = #ProductId";
DbCommand comm = new DbCommand();
comm.CommandText = query;
DbParameter param = comm.CreateParameter();
param.ParameterName = "#ProductId";
param.Value = productId;
comm.Parameters.Add(param);
DataTable table = comm.ExecuteCommand();
if (table.Rows.Count > 0)
{
return true;
}
else
return false;
}
please modify query and parameters according to your need.

Categories