I have binded a data grid to an array. Also, there is a button there to delete the row. The problem is that I am not sure how to implement it since the data source is an array.
See below
<Columns>
<asp:TemplateColumn>
<ItemTemplate>
<asp:Label ID="lblItems" runat="server" Text='<%# Container.DataItem>' />
</ItemTemplate>
</asp:TemplateColumn>
<asp:ButtonColumn ButtonType="PushButton" CommandName="Delete" Text="Delete">
</asp:ButtonColumn>
</Columns>
and here I would like to implement it..
private void DataGrid1_DeleteCommand(object source,
System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
int rowToDelete = e.Item.ItemIndex;
myDataGrid.DataBind();
}
In the code for the deletion, how can I access the index of my array based on the button clicked (per row)?
Here is an example
Markup.
<asp:DataGrid ID="DataGrid1" runat="server"
AutoGenerateColumns="False"
OnDeleteCommand="DataGrid1_DeleteCommand">
<Columns>
<asp:TemplateColumn HeaderText="Name">
<ItemTemplate>
<asp:Label ID="lblItems" runat="server"
Text='<%# Container.DataItem %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateColumn>
<asp:ButtonColumn ButtonType="PushButton"
CommandName="Delete"
HeaderText="Actions"
Text="Delete">
</asp:ButtonColumn>
</Columns>
</asp:DataGrid>
Code-behind.
private static string[] names = new string[] { "Matt", "Joanne", "Robert" };
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
BindGrid();
}
}
private void BindGrid()
{
DataGrid1.DataSource = names;
DataGrid1.DataBind();
}
protected void DataGrid1_DeleteCommand(object source, DataGridCommandEventArgs e)
{
string deletedItem = ((Label) DataGrid1.Items[e.Item.ItemIndex].FindControl("lblItems")).Text;
names = names.Where(val => val != deletedItem).ToArray();
BindGrid();
}
Hope this helps.
Have you tried to access your src object using the method below (notice this is 'RowDeleting' event on gridview)?
protected void gv_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
MyObject o = (MyObject)gv.Rows[e.RowIndex].DataItem;
}
There are also other tricks like storing an id in a hiddenfield on the row and then on the delete command you search for the control and pluck your value. My preference is the method above but really depends on what your goal is.
protected void gv_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
HiddenField field = (HiddenField)gv.Rows[e.RowIndex].FindControl("myHiddenField");
string myValue = field.Value;
// delete it and rebind
}
Related
I have a gridview in which I have manually generated a column for checkboxes as a HeaderTemplate as below
<asp:GridView ID="gvDB" runat="server" AutoGenerateColumns="False" DataKeyNames="Id" OnRowDataBound="gvDB_RowDataBound" <asp:TemplateField>
<HeaderTemplate>
<asp:CheckBox ID="chkSelectHeader" AutoPostBack="true" OnCheckedChanged="chkSelectHeader_CheckedChanged" runat="server"/>
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="chkSelect" AutoPostBack="true" runat="server" OnCheckedChanged="chkSelect_CheckedChanged1" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And OnRowDataBound I'm dynamically generating controls and adding it to the each row
e.Row.Cells[rowIndex].Controls.Add(control);
And they are binding to the columns as expected.But my chkSelectHeader_CheckedChanged chkSelect_CheckedChanged1 events are not firing.
Page Load
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
AddTemplatesToGrid();
}
BindDataToGridView();
}
public void AddTemplatesToGrid()
{
DataTable dt = new DataTable();
foreach (Employees emp in EmployeesList)
{
TemplateField tfield = new TemplateField();
tfield.HeaderText = emp.Name;
gvDataEntry.Columns.Add(tfield);
}
}
You call BindDataToGridView on every postback which will discard events.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
AddTemplatesToGrid();
}
BindDataToGridView();
}
Include BindDataToGridView() in the !Page.IsPostBack-check.
I am trying to update a value in my gridview on row updating. However, it refuses to take in the value written in the textbox. I populate the gridview if the page is not post back. Help!
GRIDVIEW:
<asp:UpdatePanel runat="server" UpdateMode=Conditional><ContentTemplate>
<asp:GridView runat="server" ID="searchGV" AutoGenerateColumns="False" GridLines="None"
CssClass="mGrid" EmptyDataText="The Search Did Not Return Any Results"
PagerStyle-CssClass="pgr" AlternatingRowStyle-CssClass="alt" Width="100%" OnRowCancelingEdit="searchGV_RowCancelingEdit"
OnRowEditing="searchGV_RowEditing" DataKeyNames="media_id" OnRowUpdating="searchGV_RowUpdating">
<Columns>
<asp:BoundField DataField="media_id" Visible="false" HeaderText="" />
<asp:BoundField DataField="dir_path" Visible="false" HeaderText="Dir" />
<asp:TemplateField HeaderText="Date Taken" >
<ItemTemplate>
<asp:LinkButton ID="dateLinkCsBtn" OnClientClick='<%#Eval("dir_path","Javascript:return test(\"{0}\",event);")%>'
runat="server" Text='<%# Bind("date") %>'></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Media Type">
<ItemTemplate>
<asp:Label runat="server" ID="mediaTypeLbl" Text='<%#Eval("description") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Alias File Name">
<ItemTemplate>
<asp:Label runat="server" ID="aliasFileName" Text='<%#Bind("alias_file_name") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox runat="server" Text='<%#Bind("alias_file_name") %>' ID="updateAliasTxt"></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowEditButton="True" />
</Columns>
</asp:GridView>
</ContentTemplate></asp:UpdatePanel>
CODE BEHIND:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
FillGrid();
}
}
protected void searchGV_RowEditing(object sender, GridViewEditEventArgs e)
{
searchGV.EditIndex = e.NewEditIndex;
FillGrid();
}
protected void searchGV_RowCancelingEdit(object sender,
GridViewCancelEditEventArgs e)
{
searchGV.EditIndex = -1;
FillGrid();
}
public void FillGrid()
{
Media_DAO media_query = new Media_DAO();
searchGV.DataSource = media_query.get_search_media(alias_file_name_txt.Text.Trim(), Convert.ToInt16(mediaTypeDDL.SelectedValue),
from_date_txt.Text.Trim(), to_date_txt.Text.Trim(), Convert.ToInt16(Session["user_id"]));
searchGV.DataBind();
}
protected void searchGV_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewRow row = searchGV.Rows[e.RowIndex];
TextBox new_alias = (TextBox)searchGV.Rows[e.RowIndex].FindControl("updateAliasTxt");
int media_id = Convert.ToInt16(searchGV.DataKeys[e.RowIndex]["media_id"]);
Media_DAO media_query2 = new Media_DAO();
media_query2.update_alias_name_by_id(media_id, new_alias.Text.Trim(), Convert.ToInt16(Session["user_id"]));
searchGV.EditIndex = -1;
FillGrid();
}
while declaring the grid you have specified only 1 *data key value*
asDataKeyNames="media_id"
DateKeys for grid view is stored in array format starting from 0.
The error may be in getting the media_id while updating. You need to change it as follows.
protected void searchGV_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewRow row = searchGV.Rows[e.RowIndex];
TextBox new_alias = (TextBox)searchGV.Rows[e.RowIndex].FindControl("updateAliasTxt");
int media_id = Convert.ToInt16(e.Keys[0]); //this will get the media_id
Media_DAO media_query2 = new Media_DAO();
media_query2.update_alias_name_by_id(media_id, new_alias.Text.Trim(), Convert.ToInt16(Session["user_id"]));
searchGV.EditIndex = -1;
FillGrid();
}
Since the earlier method was searchGV.DataKeys[e.RowIndex]["media_id"] , you might not get the media_id value if the row number which you are trying to edit is greater than 1.
The DataKeys property of GridView returns a collection of DataKey objects that represents the data key value of each row for a GridView. Thus, DataKeys[1] gives 2nd row, DataKeys[4] gives 5th row ...
Therefore, you need to use either the Value OR the Values property to access the value of a key field.
Rather than doing this:
int media_id = Convert.ToInt16(searchGV.DataKeys[e.RowIndex]["media_id"]);
do this:
int media_id = Convert.ToInt16(searchGV.DataKeys[e.RowIndex].Values["media_id"]);
// You can also use the Value property which gives the key value at index 0
int media_id = Convert.ToInt16(searchGV.DataKeys[e.RowIndex].Value);
I've searched for two days now and can't find a solution for my problem. I'm programming a webpart with connection to a database with Visual Studio.
So I've made a GridView to show some data listed in the database and the user is able to edit and update the data in it. Before you see the GridView, you have to click the button "load table". But when I click on "edit" on the GridView, the GridView dissapears and only shows up when I click the button "load table" again, with the GridView in edit-mode.
ASP
<asp:Button ID="btnload" runat="server" Text="load table"
onclick="btnload_Click" />
<asp:GridView ID="gridtable" runat="server" BackColor="White"
BorderColor="#CC9966" BorderStyle="None" BorderWidth="1px"
CellPadding="4" EnableModelValidation="True"
OnRowCancelingEdit="gridtable_RowCancelingEdit"
OnRowEditing="gridtable_RowEditing"
OnRowUpdating="gridtable_RowUpdating" >
<FooterStyle BackColor="#FFFFCC" ForeColor="#330099" />
<HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="#FFFFCC" />
<PagerStyle BackColor="#FFFFCC" ForeColor="#330099" HorizontalAlign="Center" />
<RowStyle BackColor="White" ForeColor="#330099" />
<SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="#663399" />
<Columns>
<asp:TemplateField HeaderText="P_number">
<ItemTemplate>
<%#Eval("P_number")%>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="textbox1" runat="server" Text='<%#Eval("P_number")%>'>
</asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="lastname">
<ItemTemplate>
<%#Eval("lastname")%>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="textbox2" runat="server" Text='<%#Eval("lastname")%>'>
</asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="PN_ch">
<ItemTemplate>
<%#Eval("PN_ch")%>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="textbox3" runat="server" Text='<%#Eval("PN_ch")%>'>
</asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="lastname_ch">
<ItemTemplate>
<%#Eval("lastname_ch")%>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="textbox4" runat="server" Text='<%#Eval("lastname_ch")%>'>
</asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="workplace">
<ItemTemplate>
<%#Eval("workplace")%>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="textbox5" runat="server" Text='<%#Eval("workplace")%>'>
</asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
C#
public SqlDataSource datasource;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnload_Click(object sender, EventArgs e)
{
openConnection(getconstring());
gridtable.AutoGenerateColumns = false;
gridtable.AutoGenerateEditButton = true;
datasource = new SqlDataSource(getconstring(), "SELECT * FROM T_Employees");
BindData();
}
public void BindData()
{
try
{
gridtable.DataSource = datasource;
gridtable.DataBind();
}
catch (Exception e)
{
//Do something
}
}
protected void gridtable_RowEditing(object sender, GridViewEditEventArgs e)
{
gridtable.EditIndex = e.NewEditIndex;
BindData();
}
protected void gridtable_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
//get EditIndex
GridViewRow row = gridtable.Rows[e.RowIndex];
// save changes
string pnumber = ((row.Cells[1].Controls[0]).ToString());
string lastname = ((row.Cells[2].Controls[0]).ToString());
string pn_ch = ((row.Cells[3].Controls[0]).ToString());
string lastname_ch = ((row.Cells[4].Controls[0]).ToString());
string workplace = ((row.Cells[5].Controls[0]).ToString());
//Update
datasource.UpdateCommand = "UPDATE T_Employees SET P_number='"+pnumber+"', lastname='"
+lastname+"', PN_ch='"+pn_ch+"', lastname_ch='"
+lastname_ch+"', workplace='"+workplace+"'";
datasource.Update();
//reset EditIndex
gridtabelle.EditIndex = -1;
//Bind data
BindData();
}
protected void gridtable_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
gridtable.EditIndex = -1;
BindData();
}
You need to store the datasource in session in the button click:
protected void btnload_Click(object sender, EventArgs e)
{
openConnection(getconstring());
gridtable.AutoGenerateColumns = false;
gridtable.AutoGenerateEditButton = true;
datasource = new SqlDataSource(getconstring(), "SELECT * FROM T_Employees");
Session["datasource "] = datasource
BindData();
}
Then change your bind to this:
public void BindData()
{
try
{
gridtable.DataSource = Session["datasource "] ;
gridtable.DataBind();
}
catch (Exception e)
{
//Do something
}
}
You also need to add this to the web.config:
<system.web>
<pages enableSessionState="true">
</system.web>
Or this to the page:
<%#Page enableSessionState="true">
You may just declare your datasource as in your aspx file and you're done. If you then need to bind your grid after a button click, then you have to store somewhere (eg. viewstate) a flag (boolean value) to indicate if your grid has to be binded or not. Then bind the grid only if that flag is true.
Don't need to use session at all.
Eg:
protected void Page_Load(object sender, EventArgs e)
{
if (!isPostBack){
ViewState["FLAG"] = false;
}
else{
if ((bool)ViewState["FLAG"]) BindData();
}
}
protected void btnload_Click(object sender, EventArgs e)
{
ViewState["FLAG"] = true;
}
Looking # previous answers, please consider that even if you choose ViewState or Session (each of these have their own advantages / disadvantages), you don't need to store ridundant data. In your case, just a single bit is enough, as you have the code - in your page - to build/bind the data source without storing it interely.
I have a grid view which contains a button in a template field. I want to change the button text when the button click event is completed. Can somebody send me a sample code.
Thanks in advance
Here is a sample bit of code using the RowCommand() of the GridView.
ASPX
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" onrowcommand="GridView1_RowCommand">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lbl1" runat="server"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:Button ID="Button1" runat="server" CausesValidation="false" CommandName="MYCOMMAND" Text="My Text!" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
C#
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
List<string> lst = new List<string>() { "asd", "xxx" };
GridView1.DataSource = lst;
GridView1.DataBind();
}
}
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "MYCOMMAND")
{
Button Button1 = (Button)e.CommandSource;
if (Button1 != null)
Button1.Text = "changed text..";
}
}
I stripped this example to make it simple. I have a gridview with a template field. The template field contains two buttons and a label (They must be in the same template field). I want the first button to set the label text to "Win", and the other button to set the label text to "fail". The onrowcommand doesnt seem to be triggered by buttons in a template field. How can I accomplish this?
My gridview code is below:
<asp:GridView ID="GridView1" runat="server" EnableModelValidation="True" AutoGenerateColumns="False"
OnRowCommand="Gridview1_RowCommand">
<Columns>
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:Button ID="btnWin" runat="server" CommandName="Win" Text="Win" />
<asp:Button ID="btnFail" runat="server" CommandName="Fail" Text="Fail" />
<asp:Label ID="lblStatus" runat="server" Text='<%# Bind("text") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and my code behind:
protected void Page_Load(object sender, EventArgs e)
{
DataTable myTable = new DataTable();
myTable.Columns.Add("text", typeof(string));
myTable.Rows.Add("First Entry");
myTable.Rows.Add("Second Entry");
GridView1.DataSource = myTable;
GridView1.DataBind();
}
public void Gridview1_RowCommand(Object sender, GridViewCommandEventArgs e)
{
//set lblStatus.text to "Win", or "Fail"
}
Thanks in advance!
Here you go...
public void Gridview1_RowCommand(Object sender, GridViewCommandEventArgs e)
{
lblStatus.Text = e.CommandName;
}
I see that there is more to this question than is answered here, bear with me. One way would be to delegate the OnCommand event of each button to its designated event handler, as follows:
<div>
<asp:GridView ID="MyGridView" runat="server" EnableModelValidation="true" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:Button ID="MyWinButton" runat="server" OnCommand="MyWinButton_OnCommand" CommandName="Win" Text="Win" />
<asp:Label ID="MyStatusLabel" runat="server" Text='<%# Bind("text") %>'/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
public void MyWinButton_OnCommand(Object sender, CommandEventArgs e)
{
var label = ((Button)sender).Parent.FindControl("MyStatusLabel") as Label;
label.Text = e.CommandName;
}
Also, as Alison suggests, you won't see the desired output of this unless you use !IsPostBack in Page_Load. Furthermore, on doing so this does in fact enable you to use the one row command event handler as initially suggested, albeit with a slight change in the label retrieval:
public void MyGridView_OnRowCommand(Object sender, GridViewCommandEventArgs e)
{
var label = ((Button)e.CommandSource).Parent.FindControl("MyStatusLabel") as Label;
label.Text = e.CommandName;
}
Are you using a MasterPage with ViewState turned off? Buttons in a template field with ViewState set to false will not fire.
Also, you should change your Page_Load to NOT rebind on postback"
protected void Page_Load(object sender, EventArgs e)
{
if (!page.IsPostBack) {
DataTable myTable = new DataTable();
myTable.Columns.Add("text", typeof(string));
myTable.Rows.Add("First Entry");
myTable.Rows.Add("Second Entry");
GridView1.DataSource = myTable;
GridView1.DataBind();
}
}
The rebinding may be interfering.