I have a dropdown list to search by categories.
I need help to bind my gridview at page load, but at the same time, I also have a select command as votes.
I know that there are codes such as Databinding in the pageload event. But for my case, i need to link the select command to a button to update votes. If i databind it, i could not grab the data key names to update my votes counter.
Is there any way to bind the gridview, without removing the DataSourceID in the gridview itself?
My aspx codes are as follow.
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="SELECT * FROM [Review] WHERE ([Category] = #Category)">
<SelectParameters>
<asp:ControlParameter ControlID="ddlCat" Name="Category"
PropertyName="SelectedValue" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
<asp:SqlDataSource ID="SqlDataSource2" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="SELECT [Category] FROM [ReviewCategory]">
</asp:SqlDataSource>
<asp:DropDownList ID="ddlCat" runat="server"
DataSourceID="SqlDataSource2" DataTextField="Category"
DataValueField="Category" AutoPostBack="True"
onselectedindexchanged="SelectionChange">
</asp:DropDownList>
<asp:GridView ID="GridView1" runat="server" Width="1114px"
Height="272px" AutoGenerateColumns="False" PageSize="5"
DataSourceID="SqlDataSource1" AllowPaging="True" DataKeyNames="ReviewID">
<Columns>
<asp:BoundField DataField="Votes" HeaderText="Votes"
SortExpression="Votes" />
<asp:BoundField DataField="Category" HeaderText="Category"
SortExpression="Category" />
<asp:CommandField SelectText="VOTE as your FAVOURITE!"
ShowSelectButton="True" />
</Columns>
c# code
protected void btnVote_Click(object sender, EventArgs e)
{
int reviewid = Convert.ToInt16(GridView1.SelectedDataKey.Value);
SqlConnection conn = new SqlConnection(#"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True");
string sqlstmt = "select Votes from Review where ReviewID = '" + reviewid + "'";
SqlCommand comm = new SqlCommand(sqlstmt, conn);
try
{
conn.Open();
SqlDataReader read = comm.ExecuteReader();
if (read.Read())
{
int votes = (int)read["Votes"];
votes += 1;
string updatestatement = "Update Review set Votes= '" + votes + "' Where ReviewID = '" + reviewid + "'";
SqlCommand command = new SqlCommand(updatestatement, conn);
read.Close();
command.ExecuteNonQuery();
}
}
finally {
conn.Close();
GridView1.DataBind();
}
}
protected void SelectionChange(object sender, EventArgs e)
{
int stored = ddlCat.SelectedIndex;
if (stored == 0)
{
SqlDataSource1.SelectCommand = "SELECT * from Review ORDER BY [Votes] DESC ";
}
else { }
}
You should implement the RowCommand event from the GridView. You alredy have the CommandField, so do something like this:
void GridView1_RowCommand(Object sender, GridViewCommandEventArgs e)
{
//
// Get the keys from the selected row
//
LinkButton lnkBtn = (LinkButton)e.CommandSource; //the button
GridViewRow myRow = (GridViewRow)lnkBtn.Parent.Parent; //the row
GridView myGrid = (GridView)sender; // the gridview
int reviewid = Convert.ToInt32(GridView1.DataKeys[myRow.RowIndex].Value); //value of the datakey **strong text**
// If multiple buttons are used in a GridView control, use the
// CommandName property to determine which button was clicked.
// In this case you are pressing the button Select, as ou already
// defined this at the aspx code.
if(e.CommandName=="Select")
{
// Put the logic from btnVote_Click here
}
}
The another way could be implement the SelectIndexChanging or SelectIndexChanged, given that you will use the Select Button to fire the update magic. Here the example with SelectIndexChanging.
void GridView1_SelectedIndexChanging(Object sender, GridViewSelectEventArgs e)
{
// Get the currently selected row. Because the SelectedIndexChanging event
// occurs before the select operation in the GridView control, the
// SelectedRow property cannot be used. Instead, use the Rows collection
// and the NewSelectedIndex property of the e argument passed to this
// event handler.
int reviewid = Convert.ToInt32(GridView1.DataKeys[e.NewSelectedIndex].Value); //value of the datakey **strong text**
// Put the logic from btnVote_Click here
}
Let us look into your requirements one by one:
1.) *Binding GridView at PageLoad with DropDownList:
In this case you need to retrieve the Value selected in dropdownList. Do the below setup to grab the Value from DropDownList
<asp:SqlDataSource ID="SqlDataSource2" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="SELECT [Category] FROM [ReviewCategory] where Category=#Category">
<SelectParameters><asp:ControlParameter ControlID="ddlCat" Name="Category"
PropertyName="SelectedValue" /></SelectParameters>
</asp:SqlDataSource>
What is Happenning:
Each time a value is selected in dropdown, Postback will happen( AutoPostback="true").
After the Page.PreRender Event, the DataSource controls [ SqlDatSource here ] performs the required queries and retrieve the data. So the selected DropDownList value will be used by SqlDataSource. Thus there is NO need to worry about changing/manipulating DataSourceID in any way.
2.) "But for my case, i need to link the select command to a button to update votes"
'
In this case you have a Select button inside grid View and a 'vote' button outside GridView but somewhere in your page. So, once you select any row in grid view, click the 'Vote' button. You can access the SelectedRow and Index as usual.
protected void btnVote_Click1(object sender, EventArgs e)
{
int i = CustomersGridView.SelectedIndex;
}
Note that the Click event of 'Vote' button fires before the DataSource controls perform their queries & retrieve data. So once you update the Vote count in btnVote_click event as you are doing currently, there is NO need to Bind data again. This part of your code seems fine to me.
Related
pictureIf I selected male radio button then different options show in dropdown list if I select Female then show different options in dropdown list with the help of RowDataBound Method.
Ok, in fact much of the trick and issue is that when you load the existing grid of data, we ALSO have to setup the radiobutton choice and the drop down list.
So, say we have this grid:
<asp:GridView ID="GHotels" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" cssclass="table" OnRowDataBound="GHotels_RowDataBound" >
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" />
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:TemplateField HeaderText="Gender">
<ItemTemplate>
<asp:RadioButtonList ID="RGender" runat="server"
RepeatDirection="Horizontal"
Text='<%# Eval("Gender") %>' >
<asp:ListItem>M</asp:ListItem>
<asp:ListItem>F</asp:ListItem>
</asp:RadioButtonList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Option">
<ItemTemplate>
<asp:DropDownList ID="cboOption" runat="server"
DataValueField="ID"
DataTextField="Feature" >
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
Code to load the grid is this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GHotels.DataSource = MyRst("SELECT * FROM tblHotelsA ORDER BY HotelName");
GHotels.DataBind();
}
}
public DataTable MyRst(string strSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
cmdSQL.Connection.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
And we now have this:
but, note how we STILL have to load up the radiobutton list and ALSO setup the combo box that gives a different set of choices.
So, we add this code to the row data bound event.
protected void GHotels_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView gData = e.Row.DataItem as DataRowView;
// based on Gender fill cbo box
string strSQL = "SELECT ID, Feature FROM tblHotelOptions ";
if (gData["Gender"].ToString() == "M")
{
strSQL += "WHERE Gender = 'M'";
}
else
{
strSQL += "WHERE Gender = 'F'";
}
strSQL += " ORDER BY Feature";
DropDownList cboOption = e.Row.FindControl("cboOption") as DropDownList;
cboOption.DataSource = MyRst(strSQL);
cboOption.DataBind();
cboOption.Items.Insert(0, new ListItem("Select", "0"));
if (gData["HotelOption"] != null)
cboOption.SelectedValue = gData["HotelOption"].ToString();
}
}
So, for each grid row, we process the data row information, and conditional load up the drop down list with choices based on gender.
Now, that works for "loading", but now we need to add the event and code for when we CHANGE the radio button choice.
so, in the markup, we add this event to the radiobutton:
We have to use markup and intel-sense to pop up the choice to create a new event, like this:
So, we added autopostback=true to the radio button list, and the selected change event.
So, now when you change the radio choice, we need to run code to change the drop down list choices.
So, that code can look like this:
protected void RGender_SelectedIndexChanged(object sender, EventArgs e)
{
RadioButtonList rBtn = sender as RadioButtonList;
GridViewRow gRow = rBtn.NamingContainer as GridViewRow;
string strSQL = "SELECT ID, Feature FROM tblHotelOptions ";
if (rBtn.SelectedItem.Text == "M")
// based on Gender fill cbo box
{
strSQL += "WHERE Gender = 'M'";
}
else
{
strSQL += "WHERE Gender = 'F'";
}
strSQL += " ORDER BY Feature";
DropDownList cboOption = gRow.FindControl("cboOption") as DropDownList;
cboOption.DataSource = MyRst(strSQL);
cboOption.DataBind();
cboOption.Items.Insert(0, new ListItem("Select", "0"));
}
In fact, the code is VERY much the same as how we had to load up the grid.
I am programming in ASP.NET, visual studio. I have a dropdown list created in HTML form. If I dropdown the list, it displays the record from associated column in the table. But what I want is to show the corresponding value / record with that list item.
For example in the table, I have column id, productname and price. After choosing a particular product name (from drop down list), the associated price with it must be displayed in front of it (in a label).
However, By default, I want the drop down list to shows nothing in the beginning.
UPDATE:
Store.aspx:
<form id="form1" runat="server">
<div>
Welcome
<asp:Label ID="Label3" runat="server" ></asp:Label>
<br />
<br />
Products: <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged" ></asp:DropDownList>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:ConnectionString %>" SelectCommand="SELECT * FROM [productdata]"></asp:SqlDataSource>
Price:
<asp:Label ID="Label1" runat="server" ></asp:Label>
<br />
<br />
<asp:Button ID="Button1" runat="server" Text="Add to Cart" />
<br />
<br />
Items in cart: <asp:DropDownList ID="DropDownList2" runat="server"></asp:DropDownList>
<br />
<br />
Total Price: <asp:Label ID="Label2" runat="server"></asp:Label>
</div>
</form>
Store.aspx.cs:
public partial class Store : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Label3.Text = Request.QueryString["name"];//show welcome text
String cs = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
if (!IsPostBack)
{
using (SqlConnection sc = new SqlConnection(cs))
{
SqlCommand sqlcom = new SqlCommand("Select id, productname, price from productdata", sc);
sc.Open();
DropDownList1.DataTextField = "productname";//show in the dropdown list
DropDownList1.DataValueField = "price"; //show in the label
DropDownList1.DataSource = sqlcom.ExecuteReader();
DropDownList1.DataBind();
}
}
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
String cs = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
SqlDataReader rd;
using (SqlConnection sc = new SqlConnection(cs))
{
SqlCommand sqlcom = new SqlCommand("Select id, productname, price from productdata where id=" + Convert.ToUInt32(DropDownList1.SelectedValue), sc);
sc.Open();
rd = sqlcom.ExecuteReader();
if (rd.Read())
{
Label1.Text = rd[2].ToString();
}
sc.Close();
}
}
}
Database:
CREATE TABLE [dbo].[productdata] (
[Id] INT NOT NULL,
[productname] VARCHAR (50) NULL,
[price] FLOAT (53) NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
This Edit according to using AutoPostBack=True and if (!IsPostBack) in Page_Load thanks to Arindam:
For simply solution using postback event:
First you should add OnSelectedIndexChanged event for dropdownlist
<asp:DropDownList ID="DropDownList1" runat="server"
OnSelectedIndexChanged="GetPrice" AutoPostBack="true">
</asp:DropDownList>
Then in code behind you just get selected value and fill to the label price
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Label3.Text = Request.QueryString["name"];//show welcome text
String cs = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
using (SqlConnection sc = new SqlConnection(cs))
{
SqlCommand sqlcom = new SqlCommand("Select id, productname, price from productdata", sc);
sc.Open();
DropDownList1.DataTextField = "productname";//show in the dropdown list
DropDownList1.DataValueField = "price"; //show in the label
DropDownList1.DataSource = sqlcom.ExecuteReader();
DropDownList1.DataBind();
}
}
}
protected void GetPrice(object sender, EventArgs e)
{
Label1.Text = DropDownList1.SelectedValue;
}
You have to use AutoPostBack=True so that when you change index of dropdownlist, it will trigger a postback to server so the function GetPrice(...) will be called.
Every time the page postback, it will call function Page_Load(...) first, so you must use propertive IsPostBack to check if case1_this is the first time the page is loaded, or case2_a postback event, and you only set the ddl datasource at case1 because if you set datasource, by default the dropdownlist will reset to select first item in list.
When you go advance, you should consider using Javascript and Jquery to solve this, so the page will not load again like this postback solution.
And one more thing, you should name your controls well, don't make them default like that. It's one of two hard things in programming.
Yes you can but if not please use datatable and i am sure that work fine .if u not able do that just post I will give the correction.
Trying to update my DB from the edit/update functionality of a GridView. What ever I try, I can't seem to be working.
How can I update my SQLDatasource using the information entered in the GridView edit textbox?
Here is what I have:
.cs:
DS.UpdateCommand = "UPDATE tbSystems SET Systems = #Systems WHERE id = #id";
DS.Update();
.aspx:
<asp:GridView ID="gv1"
runat="server"
CellPadding="2"
DataKeyNames="id"
AutoGenerateDeleteButton="True"
AutoGenerateEditButton="True"
OnRowDeleting="gv1_RowDeleting"
OnRowDeleted="gv1_RowDeleted"
OnRowUpdating="gv1_RowUpdating" OnRowEditing="gv1_RowEditing" OnRowUpdated="gv1_RowUpdated">
</asp:GridView>
<asp:SqlDataSource ID="DS" runat="server" ConnectionString="<%$ ConnectionStrings:conn %>">
<UpdateParameters>
<asp:Parameter Name="Systems" Type="String" />
</UpdateParameters>
</asp:SqlDataSource>
I get this error:
Must declare the scalar variable "#id".
Shouldn't the id variable be declared already since I have it
declared in the DataKeyNames of the GridView or should I create an update parameter in the SQLDataSource?
How do I get the new value in the textbox of the GridView? This line of code always give the old value regardless in which event (edit event, updating event or updated event) I put it in:
Response.Write(((TextBox)gv1.Rows[e.NewEditIndex].Cells[2].Controls[0]).Text);
How do I manage the #variables?
Your help is greatly appreciated.
You don't need any code to connect a GridView to a SqlDataSource control. Just set the relevant properties on the controls and it will just work:
<asp:GridView ID="gv1" runat="server"
DataSourceID="DS"
DataKeyNames="id"
AutoGenerateDeleteButton="True"
AutoGenerateEditButton="True"
/>
<asp:SqlDataSource ID="DS" runat="server"
ConnectionString="<%$ ConnectionStrings:conn %>"
SelectCommand="SELECT * FROM tbSystems"
UpdateCommand="UPDATE tbSystems SET Systems = #Systems WHERE id = #id"
DeleteCommand="DELETE tbSystems WHERE id = #id"
>
<UpdateParameters>
<asp:Parameter Name="id" Type="Int32" />
<asp:Parameter Name="Systems" Type="String" />
</UpdateParameters>
<DeleteParameters>
<asp:Parameter Name="id" Type="Int32" />
</DeleteParameters>
</asp:SqlDataSource>
The important properties are:
DataSourceID - connects the GridView to the SqlDataSource;
SelectCommand - specifies the SQL command used to fill the GridView;
UpdateCommand - specifies the SQL command used to update a record;
UpdateParameters - defines the parameters passed to the UpdateCommand;
DeleteCommand - specifies the SQL command used to delete a record;
DeleteParameters - defines the parameters passed to the DeleteCommand;
With those properties in place, you can get rid of the event handlers in the code-behind. The data source control will take care of everything for you.
ASP.NET Data-Bound Web Server Controls Overview
Data Source Controls Overview
Thanks to the Naveen and lots of tweeking, I finally got to make it work. Here is how I did it. It may not be the best practices but it works.
Put the SQLDataSource in a Session. I don't knkow if this is the right thing to do, however it is the only way I found to catch the value of the gridview edit textbox.
if (!Page.IsPostBack)
{
DS.SelectCommand = "SELECT * FROM tbSystems";
Session["myDS"] = DS;
BindData();
}
Created a BindData function: (gv1 being my GridView)
private void BindData()
{
gv1.DataSource = Session["myDS"];
gv1.DataBind();
}
In the RowEditing function, I've changed the gv1 edit index to the event new edit index.
protected void gv1_RowEditing(object sender, GridViewEditEventArgs e)
{
gv1.EditIndex = e.NewEditIndex;
//Bind data to the GridView control.
BindData();
And this is the update code.
protected void gv1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
DS.UpdateCommand = "UPDATE tbSystems SET Systems = #Systems WHERE id = #id";
var id = gv1.DataKeys[e.RowIndex]["id"];
var systems = ((TextBox)gv1.Rows[e.RowIndex].Cells[2].Controls[0]).Text;
DS.UpdateParameters.Add("id",id.ToString());
DS.UpdateParameters.Add("Systems",systems);
DS.Update();
gv1.EditIndex = -1;
BindData();
}
Hopefully this will help some of you.
Thanks,
Shouldn't the id variable be declared already since I have it declared
in the DataKeyNames of the GridView or should I create an update
parameter in the SQLDataSource?
No. You must fetch the value like this
var id = GridView1.DataKeys[e.RowIndex]["id"];
How do I get the new value in the textbox of the GridView? This line
of code always give the old value regardless in which event (edit
event, updating event or updated event) I put it in
You should be using the RowUpdating event. MSDN sample code here.
How do I manage the #variables?
var systems = ((TextBox)gv1.Rows[e.RowIndex].Cells[2].Controls[0]).Text;
DS.UpdateParameters.Add("#id", id);
DS.UpdateParameters.Add("#Systems", systems);
I want to bind a Hidden Field because I want to pass a value from code behind to the asp:Parameter Name="HOME_TEAM_COACH_ID" Type="Int32".
My asp:
<asp:FormView ID="FormView1" runat="server" OnItemUpdated="FormView1_ItemUpdating" >
<EditItemTemplate>
HOME_TEAM:
<asp:DropDownList ID="DropDownListHometeam" runat="server"
DataSourceID="SqlDataGetTeams"
DataTextField="NAME" DataValueField="ID" SelectedValue='<%# Bind("HOME_TEAM_ID") %>'>
</asp:DropDownList>
<asp:HiddenField runat="server" ID="testLabel" Value='<%# Bind("HOME_TEAM_COACH_ID") %>' />
</EditItemTemplate>
And c# behind is:
protected void FormView1_ItemUpdating(object sender, FormViewUpdatedEventArgs e)
{
if (FormView1.CurrentMode == FormViewMode.Edit)
{
DropDownList HomeTeamId = FormView1.FindControl("DropDownListHometeam") as DropDownList;
string team = string.Format("{0}", HomeTeamId.Text);
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["BasketballConnectionString1"].ToString());
conn.Open();
string queryHome = "SELECT dbo.COACH.ID, dbo.COACH.SURENAME FROM dbo.COACH INNER JOIN dbo.GAMES ON dbo.COACH.TEAM_ID = dbo.GAMES.HOME_TEAM_ID WHERE (dbo.GAMES.HOME_TEAM_ID =" + team + ")";
SqlCommand cmd = new SqlCommand(queryHome, conn);
var Home_Coach_Id = cmd.ExecuteScalar().ToString();
HiddenField HomeCoachIdLabel = FormView1.FindControl("testLabel") as HiddenField;
HomeCoachIdLabel.Value = Convert.ToString(Home_Coach_Id);
conn.Close();
I want Help with the last four lines where I want to pass the Home_Coach_Id value to bind the asp:HiddenField ID="testLabel" Value='<%# Bind("HOME_TEAM_COACH_ID") %>'.
When I click update, it doesn't change the value in database. (When I debug, in the last lines it gives me the correct HomeCoachIdLabel.Value.)
any suggestions?
You do not need the explicitly set the HiddenField's Value property, because it is done by the <%# Bind("HOME_TEAM_COACH_ID") %> in your markup.
I believe your problem is that you are not returning the HOME_TEAM_COACH_ID from your query to the database in your SELECT statement:
SELECT dbo.COACH.ID, dbo.COACH.SURENAME FROM dbo.COACH
INNER JOIN dbo.GAMES ON dbo.COACH.TEAM_ID = dbo.GAMES.HOME_TEAM_ID
WHERE (dbo.GAMES.HOME_TEAM_ID =" + team + ")
The problem is that it needs the method prerender and not the method onitemupdated.
asp:FormView ID="FormView1" runat="server" OnPreRender="FormView1_OnPreRender" >
and also in c#
protected void FormView1_OnPreRender(object sender, FormViewUpdatedEventArgs e)
{
It also works when I put it in page load{ }.
The next step is to make the insert event....
I have two web pages- the first is a GridView and the second is a FormView. I have been able to retrieve the DataKey value from the GridView and pass it to the FormView page. Now I need to use that key value for my selection query. How do I assign that value? Code example would help in C#.
This is my page_load code:
protected void Page_Load(object sender, EventArgs e)
{
string CompanyStr = Server.HtmlEncode(Request.QueryString["param1"]);
string ClientKey = Request.QueryString["param2"];
Label lbl = FormView1.FindControl("CompanyID") as Label;
lbl.Text = CompanyStr;
}
And this is the FormView code:
<asp:FormView ID="FormView1" runat="server" DefaultMode="Insert" DataKeyNames="ClientKey"
DataSourceID="SqlDataSource1" onitemcommand="onItemCommand">
The ClientKey is the variable that needs to be set.
It sounds like you want to use a Select Parameter in your SQLDataSource1 markup (the one referenced in your FormView declaration) to do this. This should work:
<asp:SqlDataSource ID="SQLDataSource1" runat="server"
ConnectionString="Your Connection Strong" SelectCommand="SELECT * FROM [yourTableName] WHERE ClientKey = #ClientKey">
<SelectParameters>
<asp:QueryStringParameter Name="ClientKey" QueryStringField="param2" />
</SelectParameters>
</asp:SqlDataSource>
Notice the WHERE clause in the SelectCommand property. I don't know what the rest of your query looks like, but having that on the end should filter your FormView down to what you want.
This should automatically pull the value from your query string, and your FormView will have the proper record loaded.