How do I get the value of a Cell in a GridView? - c#

I have review various questions here, regarding this, however I still cannot get this to work.
I have a grid view (OrderList) and in this gridview I have a column with a button to simply update a particular field (basically mark an order as accepted).
In the aspx file I have the following code
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="ButtonToAcceptOrder" runat="server" Text="Accept Order" CommandName="AcceptOrder" CommandArgument="<%# ((GridViewRow) Container).RowIndex %>" />
</ItemTemplate>
</asp:TemplateField>
In the code Behind file, I have the following code:
protected void OrderList_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName =="AcceptOrder")
{
// Retrieve the row index stored in the
// CommandArgument property.
int index = Convert.ToInt32(e.CommandArgument);
// Retrieve the row that contains the button
// from the Rows collection.
GridViewRow row = OrderList.Rows[index];
Int32 oId = Int32.Parse(row.Cells[1].Text);
//Code to Update database by order id
}
}
The error is coming from oId telling that the input is not in the correct format.
In the first column of the gridview I am displaying the ID of that I require. Whilst the other columns are showing the other details.
If you spot any problems in my code can you kindly help?
(I have previously followed this tutorial: http://msdn.microsoft.com/en-us/library/vstudio/bb907626(v=vs.100).aspx)

If you have an unique id for each row, then you should be using the DataKeyNames property of the GridView.
<GridView id="OrderList" DataKeyNames="oId"... />
Then in your RowCommand code, access it like this:
Int32 oId = OrderList.DataKeys[row.DataItemIndex].Value;
This is much cleaner than trying to get value from a cell.

Related

Rowdeleteing event in Gridview

I have been trying to write this simple logic of deleting a row from the gridview and from the SQL database of the selected row, but keep getting a null reference to cell, which has the primary key [ID] in a field.
Here's my html:
<asp:GridView ID="grvInventoryEdit" runat="server" BackColor="White" onrowdeleting="grvInventoryEdit_RowDeleting"
onrowediting="grvInventoryEdit_RowEditing"
onrowupdating="grvInventoryEdit_RowUpdating">
<Columns>
<asp:CommandField ShowEditButton="True" />
<asp:CommandField ShowDeleteButton="True" /><asp:TemplateField HeaderText="Id">
<ItemTemplate>
<%#Eval("No")%>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox runat="server" ID="txtEditNo" ReadOnly="True" Text='<%#Eval("No")%>'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>........ </Columns> </asp:GridView>
And my back-end code for rowdeleting event is :
protected void grvInventoryEdit_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
TextBox id = (TextBox)grvInventoryEdit.Rows[e.RowIndex].FindControl("txtEditNo");
Asset asset = db.Assets.Single(a => a.No == Convert.ToInt32(id));
db.Assets.DeleteOnSubmit(asset);
db.SubmitChanges();
binddata();
}
and when the event fires, this is what i am seeing while debugging:
I am not sure why i am getting a null value ,though, there is a value for that cell.
Could you tell me what i am doing wrong ?
Regards,
Might be it is due to the readonly property of textbox, not suer.
If you want to use the image button for edit and delete then use
protected void ibtnDelete_Click(object sender, ImageClickEventArgs e)
{
GridViewRow gvRow = (GridViewRow)((ImageButton)sender).NamingContainer;
Int32 UserId = Convert.ToInt32(gvUsers.DataKeys[gvRow.RowIndex].Value);
// delete and hide the row from grid view
if (DeleteUserByID(UserId))
gvRow.Visible = false;
}
For complete code see
You are passing TextBox object instead instead of Text property of TextBox
Asset asset = db.Assets.Single(x=>x.No == Convert.ToInt32(id.Text));
and your TextBox is also coming null means it's unable to find it in GridView, try like this:
TextBox id = e.Row.FindControl("txtEditNo");
Also see this CodeProject article to understand how to use ItemTemplate and EditItemTemplate
why are you adding a second commandfield instead of just enabling the delete button on the existing one.
if you are using a command field you should be supplying an compatible datasource that provides Delete functionality
if you're "rolling your own" delete functionality then just use a regular Button control and supply a CommandName and CommandArgument, such as CommandName="MyDelete" CommandArgument=<row number> where <row number> is supplied via GridView RowDataBound() event.
Regardless of how you choose to implement Delete you should be placing the key field in the GridView DataKeys Property and not as a field within each row. This will make obtaining the PK far easier than what you are trying to do
I guess, in my HTML, i have only the value that's bound to the item, is being displayed, and there are no textboxes in my <ItemTemplate>, hence, it pulls null value. Whereas, in my <EditItemTemplate> there is a textbox, which can pull the value from the cell.
So I changed my HTML to this:
<asp:TemplateField HeaderText="Id">
<ItemTemplate>`<asp:label runat="server" ID="lblEditNo" ReadOnly="True" Text='<%#Eval("No")%>'></asp:label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox runat="server" ID="txtEditNo" ReadOnly="True" Text='<%#Eval("No")%>'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
and no change in my codebehind, and this resolved the issue.

Data Grid View Hyper Link in ASP.Net C#

Hi I am using DataGridView by mapping URL from database which i have given it in Hyperlinkfield (for eg: there will be 10-20 links will be displayed in the datagridview) if the particular person clicks the particular link then it has to redirect to that particular URL by incrementing the Count column in the Database for that particular URL.
Note : iam using the datagridview in the template design mode.
You can do it in the row command event
create a dynamic click with the url you wish to give
use CommandArgument and do your stuff in Gridview onrowcommand event.
<asp:GridView ID="GridView1" OnRowCommand="GridView1_RowCommand" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="btnUpdate" runat="server" CommandArgument='<%#Eval("LinkID")%>' CommandName="btnUpdate" Text='<%#Eval("LinkDisplayText")%>'>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
protected void GridView1_RowCommand(Object sender, GridViewCommandEventArgs e)
{
if(e.CommandName=="btnUpdate")
{
int index = Convert.ToInt32(e.CommandArgument);
//based on LinkID get the current click count from database.
int icount;
//increment the count
//update the database once again and get the link as well.
//redirect to the link
Response.Redirect("");
}
}

DataGrid and formatting data

I'm new to ASP.NET and don't really understand how to display a table with database data. The data is loaded in an object, where I have a list of objects.
Now I want to show a table with some columns, an image (path created from two fields in the object), an link (passing one field of the object), a textarea (id from object, value from object), a radiobutton (id from object).
How should I do this. I have tried binding a datagrid to the list of objects, and it works. But I don't want to show all data members, and I don't know how to create correct headers and the image and form controls.
ImageDataGridView.DataSource = tradeObj.Images;
ImageDataGridView.DataBind();
To stop the automatic creation of a column for each column in the data source, set:
ImageDataGridView.AutoGenerateColumns = false
Then you need to define a column for each column in the data source that you want to display - depending on the column you may want a bound column (you can control the format) or something more involved.
See http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.datagrid.columns.aspx for a sample and the different column types available
You can spefify your column and header using boundfield
<asp:boundfield datafield="yourColumn"
headertext="theHeaderText"/>
And you need to turn off:
ImageDataGridView.AutoGenerateColumns = false
To format values look at this link at msdn.
You need to use template field to customize your datagrid as per below
<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:TemplateField ShowHeader="True">
<ItemTemplate>
<asp:Image runat="server" ID="Image1"
ImageUrl="Enabled.gif" />
</ItemTemplate>
</asp:TemplateField>
......
......
</Columns>
</asp:GridView>
See this msdn link to work with template field in datagrid
Update
For iterate through every row of gridview you need to handle Rowdatabound event as per below.
protected void gridView_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
Image imgCtrl = (Image) e.Row.FindControl("imgCtrl");
imgCtrl.ImageUrl = "you can apply any format of url here";
}
}
for more information of Rowdatabound event visit this link
Just set autogenerate to false on your datagrid/gridview control. You can then create a templateField column & drop a label or textbox control inside itemTemplate & bind them like
<asp:Label ID="lblMyColumn" Text="<%# Bind("YourColumnName") %>' runat="server"></asp:Label>
Alternatively you can also drop a boundField & set its properties
<asp:BoundField DataField="YourColumnName" HeaderText="Your Text" SortExpression="YourColumnName" />

How to get selected value for dropdown list inside gridview?

Scenarios
I am using DataGrid with a column containing DropDownList. When I update the values, the DropDownList value does not get updated.
My Research so far
I believe it needs some C# code to made the DropDownList editable. I don't know where to put the code and how? Is there a shorter way than C# code?
Thank you very much
Edit : Supplied Code
student_table : id, name, major, favorite_teacher
teacher_table : id, name
The gridview has datasource of student. The DropDownList has datasource of teacher.
In the gridview with, I have made favorite_teacher as template field (DropDownList) and has teacher_table as datasource. In the edit mode, the DropDownList shows correct and populates teachers from the teacher table. When I select a favourite teacher for any student and click submit, the submit does not go through. I might need some C# code or otherwise. Don't know how to fix this problem.
Please try the below code and let me know if it's fixed:
protected void btnClick_Click(object sender, EventArgs e)
{
var tmpValue = ((DropDownList)gvRowItem.Cells[/*cellId*/].FindControl("/*dropDownListId*/")).SelectedValue;
}
You can try the following code
DataSourceID="sds_teacher_table" is referring to the teacher_table. the gridview will be referring to the student_table
<asp:TemplateField HeaderText="Favourite Teacher" >
<ItemTemplate>
<asp:Label ID="lblfavorite_teacher" runat="server" Text='<%# LookupTeacherName(DataBinder.Eval(Container.DataItem, "id")) %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlfavorite_teacher" runat="server" DataSourceID="sds_teacher_table" DataTextField="name" DataValueField="id" SelectedValue='<%#Bind("id")%>' Width="98%">
</asp:DropDownList>
</EditItemTemplate>
<FooterTemplate>
<asp:DropDownList ID="ddlNewfavorite_teacher" runat="server" DataSourceID="sds_teacher_table" DataTextField="name" DataValueField="id" SelectedValue='<%#Bind("id")%>' Width="95%">
</asp:DropDownList>
</FooterTemplate>
<ItemStyle Width="25%" />
</asp:TemplateField>
protected string LookupTeacherName(object idObj)
{
if (string.IsNullOrEmpty(idObj.ToString()))
return null;
string TeacherId = idObj.ToString();
// find the corresponding name
IEnumerator enumos = sds_teacher_table.Select(new DataSourceSelectArguments()).GetEnumerator();
while (enumos.MoveNext())
{
DataRowView row = enumos.Current as DataRowView;
if ((string)row["id"].ToString() == TeacherId)
return string.Concat(row["name"].ToString());
}
return TeacherId;
}
I implemented this from a tutorial here without writing any C# code.
You do not need C# code, although you can implement it using C# code as well.
There is a trick that you have to implement. You need to bind the values of gridview to a datasource of the other table that you want to fetch data from. But by design, since dropdown list is contained in GridView, it can only be bound to gridview fields. This is the main complication.
To overcome that, include those additional fields in the gridview. You may need to use join statement so that you can include all the fields that you need in gridview. Now you can easily bind those fields to DropDownlist. Of course you do not need to show these extra values in GridView, they are there only for DropDownList. This will solve your problem, without writing a single line of code.

C# Linq to datagrid with update functionality

I wanted to do a datagrid that had the allowed a user to edit current information as well as add new stuff. I also need it to have a checkbox in there that I can respond to. Basically it would be a name, and an isActive field that was represented by a checkbox in each row of the datagrid.
I would like to use linq for this but am not sure if it's even possible. This is a ASP.Net website.
If anyone had any feedback that would be awesome.
Easy enough to do.
The GridView has a number of events that you can use for certain operations (Delete, Edit, Cancel, and Update). For example, the OnRowUpdating and OnRowEditing would look like thus:
<asp:GridView ID="gvTest" runat="Server" OnRowUpdating="gvTest_RowUpdating" OnRowEditing="gvTest_RowEditing">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnUpdate" runat="Server" Text="Update" CommandName="Update">
<asp:Button ID="btnEdit" runat="Server" Text="Edit" CommandName="Edit">
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Then implement the event handlers for the update (edit, delete, etc.) in your codebehind. To make life easier for yourself, you can switch over to Design view, find your GridView and bring up the Events (the icon that looks like a lightning bolt) and then double click an event and the stub of it will automatically be created for you in the codebehind and the html markup will automatically be created as well. An example of the RowUpdating event handler would look like thus:
protected void gvTest_RowUpdating(object sender, GridViewUpdateEventArgs e) {
// Convenient access to the row index that was selected
int theRowIndex = e.RowIndex;
GridViewRow gvr = gvTest.Rows[e.RowIndex];
// Now its just a matter of tracking down your various controls in the row and doing
// whatever you need to with them
TextBox someTxtBox = (TextBox)gvr.FindControl("theTextBoxID");
DropDownList someDDL = (DropDownList)gvr.FindControl("theDDL_ID");
// Perhaps some business class that you have setup to take the value of the textbox
// and insert it into a table
MyDoSomethingClass foo = new MyDoSomethingClass {
FirstName = someTxtBox.Text,
Age = someDDL.SelectedItem.Value
};
foo.InsertPerson();
}
Note that you can also use the OnRowCommand instead of using Update (Edit, Delete, etc.) events, but the OnRowCommand doesn't have the selected row index readily available for you. If you want it then you have to do a little magic in your markup.
<asp:Button ID="btnDoSomething" runat="Server" Text="Do Something" CommandArgument="<%# Container.DataItemIndex %>" CommandName="DoSomething">
And then in the RowCommand event you do something like this to get at the row index:
protected void gvTest_RowCommand(object sender, GridViewCommandEventArgs e) {
int rowIdx = Convert.ToInt32(e.CommandArgument);
}
EDIT:
Accessing the key(s) that your GridView is bound to is quite simple, actually. Assuming that your GridView is bound to only one key, you can get the key in this manner (assume that we're in the RowCommand event):
int rowIdx = Convert.ToInt32(e.CommandArgument);
int someKeyID = Convert.ToInt32(gvTest.DataKeys[rowIdx].Value);

Categories

Resources