How can i get the value of a field that is set to Visible=false? as follows:
<asp:BoundField DataField="ItemID" HeaderText="Line Item ID" Visible="false"/>
but when i try to get it with
int temID = Convert.ToInt32(row.Cells[0].Text);
It cant find it and throws an exception, but if I make it Visible="true" it works.
How can I retrieve the value if visible = false?
In the definition of your GridView, add
<asp:GridView .... DataKeyNames="ItemID" ...>
You also need to use OnRowDataBound, not OnDataBound
<asp:GridView .... DataKeyNames="ItemID" ... OnRowDataBound="GridView_RowDataBound">
Then in your code behind, something like this
protected void GridView_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
int ItemId = Int32.Parse(YourGridView.DataKeys[e.Row.RowIndex].Values[0].ToString());
}
}
I did not test this code before posting. But this is the general idea of what you need to do. It may or may not work as is.
Another way without all those code is something like that:
<style type="text/css">
.Hide
{
display: none;
}
</style>
in the page or in your css file.
And set this class to your boundField:
<asp:BoundField DataField="Id" ItemStyle-CssClass="Hide" HeaderStyle-CssClass="Hide" />
Hope this help.
I wrestled with this for a bit, but ended up (instead of adding RowDataBound events), simply getting the values out of the DataKeys when I needed them, eg (in VB):
x = MyGrid.DataKeys(oRow.RowIndex).Values(0).ToString)
Obviously this is suitable for when the values are data keys... when not it's probably not a good idea.
If you have IsVisible=false the control is not rendered at all to the client and hence you won't be able to get the value back on postback. You can use style display:none to not display it on the client, but still being rendered.
<asp:BoundField DataField="ItemID" HeaderText="Line Item ID" style="display:none;"/>
In this case you'll be able to get the value back.
An alternative to this would be to use <input type="hidden" runat="server"> control.
try adding the attribute
runat="Server"
Related
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.
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" />
I have a GridView that displays data on three columns. On the third column I have a CheckBox. I have two things that I need to achieve
CheckBox will be checked based on the column value (1,0)
If it is checked the rest of the two columns should display #### However the data for the two columns should remain in the database.
How can this be achieved?
Can I find the CheckBox on RowDataBound event and check the value and make the CheckBox checked and unchecked? How about making the other columns ####?
NEW Comments:
string str = ((System.Data.DataRowView)(e.Row.DataItem)).Row.ItemArray[2].ToString();
this helps to set the checkbox checked or not.
if checked is true I am trying the following.
((System.Data.DataRowView)(e.Row.DataItem)).Row.ItemArray[0] = "#####";
((System.Data.DataRowView)(e.Row.DataItem)).Row.ItemArray[1] = "#####";
((System.Data.DataRowView)(e.Row.DataItem)).Row.AcceptChanges();
It is displaying the gridview checkbox as checked but the column value is not changed to "####"
You can turn your item columns into TemplateColumns and do the following which will localize your code to the control level and you don't have to worry about all the searching. I pefer to never use the built in column types because there are usually future enhancements that require changing the columns to TemplateColumns anyways. It also gives you a lot of flexibiltiy on useage.
Here is an example:
<asp:GridView ID="grdYourGrid" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField HeaderText="YourField1">
<ItemTemplate>
<asp:Literal runat="server" ID="ltYourField1"
OnDataBinding="ltYourField1_DataBinding" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="YourField2">
<ItemTemplate>
<asp:Literal runat="server" ID="ltYourField2"
OnDataBinding="ltYourField2_DataBinding" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="YourCheckBoxField">
<ItemTemplate>
<asp:CheckBox runat="server" ID="chkYourCheckBoxField"
OnDataBinding="chkYourCheckBoxField_DataBinding" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Then in your codebehind implement each control's OnDataBinding:
protected void ltYourField1_DataBinding(object sender, System.EventArgs e)
{
Literal lt = (Literal)(sender);
lt.Text = (bool)(Eval("YourCheckBoxField")) ?
"##########" : Eval("YourField1");
}
protected void ltYourField2_DataBinding(object sender, System.EventArgs e)
{
Literal lt = (Literal)(sender);
lt.Text = (bool)(Eval("YourCheckBoxField")) ?
"##########" : Eval("YourField2");
}
protected void chkYourCheckBoxField_DataBinding(object sender, System.EventArgs e)
{
CheckBox chk = (CheckBox)(sender);
chk.Checked = (bool)(Eval("YourCheckBoxField"));
}
The advantages to doing it this way is your could replace code easily as it is all isolated and has no 'searching' for expected controls. I very rarely use the RowDataBound event because it makes you have to write specific code to look for the controls and it makes more sense to me to have the code localized to the control. If someone changes something they know there are ONLY affecting that one control instead of everything on the row possibly as a side effect. You could also use the <%# method and do the Evals right in the markup but I personally prefer to never have any code in the aspx markup at all.
I have a gridview for which I programmatically set the datasource and databind it to a collection of objects. For each row that is created I then use different methods in the fields to extract the relevant information from the object like this one:
<asp:TemplateField HeaderText="Aliases">
<ItemTemplate>
<%# ( (MyItem)Container.DataItem).Aliases.ToString() %>
</ItemTemplate>
</asp:TemplateField>
My problem is that in the OnRowDeleting method I would preferably like to be able to access that DataItem using e g MyGridView.Rows[e.RowIndex].DataItem or in other way. But I can’t find how to configure the Gridview to retain the DataItem. Is it possible to access the DataItem used and how would I configure it to do it? If that’s not possible can I access the values that are bind by the methods? Or do I have to go with plan B and rewrite the datasource object collection to a datatable and then use datakeysnames?
MyGridView.Rows[e.RowIndex].DataItem should generally work but I guess that you are probably relying the view-state for retaining grid data on post-backs. In such case, you will get the DataItem property as NULL.
Work-around can be to always re-bind the grid with actual data in each postback early in page life cycle (say page_load).
However, in your case, you can very well use DataKeyNames. Contrary to your belief, you don't need a DataTable for this property to work. For example, if your class has property named ItemId indicating the key for your object then you can use DataKeyNames="ItemId" in the markup and refer it in OnRowDeleting using Keys property of event arguments.
According to MSDN:
"The DataItem property is only available during and after the RowDataBound event of a GridView control."
Therefore, access the DataItem in the RowDataBound event:
Lets say you bind a List(Of Vehicle) to the grid:
Dim vehicles As List(Of Vehicle) = Vehicle.GetAll()
gvVehicles.DataSource = vehicles
gvVehicles.DataBind()
In the RowDataBound event access the DataItem:
Protected Sub gvVehicles_RowDataBound(sender As Object, e As GridViewRowEventArgs)
If e.Row.RowType = DataControlRowType.DataRow Then
Dim veh As Vehicle = TryCast(e.Row.DataItem, Vehicle)
If Not veh Is Nothing Then
Dim chkBox As CheckBox = CType(e.Row.FindControl("chkSelect"), CheckBox)
chkBox.Checked = True
End If
End If
End Sub
I'm aware this is very dated question at this point - however, I've just run into a similar issue and none of these answers resolved the issue; so I figured I'd post an alternative solution. In my scenario, the issue was on the OnSelectedIndexChanged event. So, it should theoretically hold true for OnRowDeleting but not necessarily on OnRowDeleted (depending on where exactly in the process the row is deleted).
My solution was to simply add a HiddenField for the data that I didn't want to be visible in the GridView, for example:
<asp:GridView ID="gvTutorGroups" runat="server" AutoGenerateColumns="False" DataSourceID="sqlTutorGroups" DataKeyNames="TTGP_Group_Code" AllowPaging="True" PageSize="8" EmptyDataText="You have no tutor groups to display." Style="margin: 0 auto; width: 870px;" OnRowDataBound="gvTutorGroups_RowDataBound" OnSelectedIndexChanged="gvTutorGroups_SelectedIndexChanged">
<Columns>
<asp:TemplateField >
<ItemTemplate>
<asp:HiddenField runat="server" ID="hfTTGPISN" Value="<%# Eval("TTGP_ISN") %>" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="TTGP_Group_Code" HeaderText="TG Code" />
<asp:BoundField DataField="PRPH_Title" HeaderText="Name" />
<asp:BoundField DataField="TTGP_Start_Date" HeaderText="Start Date" DataFormatString="{0:d}" />
<asp:BoundField DataField="TTGP_End_Date" HeaderText="End Date" DataFormatString="{0:d}" />
</Columns>
</asp:GridView>
Then I just used the FindControl method to access that field, like so:
protected void gvTutorGroups_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (GridViewRow row in gvTutorGroups.Rows)
{
if (row.RowIndex == gvTutorGroups.SelectedIndex)
{
row.CssClass = "rowSelected";
DataRowView dataItem = (DataRowView)row.DataItem;
HiddenField hfTGIsn = (HiddenField)this.Parent.FindControl("hfTGisn");
hfTGIsn.Value = ((HiddenField)row.FindControl("hfTTGPISN")).Value;
}
else
{
row.CssClass = "";
}
}
}
It's not an ideal solution, but it works.
I trying to pass some values that the user selects but I am unable to set the CheckBoxField in my gridview.
Could someone please let me know how to do this?
Here is my code so far...
<asp:GridView ID="GridView1" SkinID="CompacGrid" runat="server" AutoGenerateColumns="False"
DataSourceID="ObjectDataSource1" Width="400px" AllowPaging="True" BackColor="White"
BorderColor="#999999" BorderStyle="None" BorderWidth="1px" CellPadding="3"
GridLines="Vertical">
<RowStyle BackColor="#EEEEEE" ForeColor="Black" />
<Columns>
<asp:CheckBoxField headertext="mm" />
Thank you,
Steve
For some reason, Microsoft omitted the 'Value' property from its specification for CheckBox in ASP.NET, despite it being a completely valid feature of HTML. My guess is that they wanted it to be as similar to the WinForms CheckBox as possible (which also lacks a 'Value' property).
If you want to give your <asp:CheckBox /> or <asp:CheckBoxField /> a 'Value' property you will either have to extend the control yourself and define a custom 'Value' property, or make use of the code-behind to populate the Attributes or InputAttributes collection of the control. See this article for more details.
cbMyCheckBoxField.Attributes.Add("Value", "foo");
or
cbMyCheckBoxField.InputAttributes.Add("Value", "foo");
The main difference between these two approaches is that the former will not include the Value in the generated HTML (only ViewState), while the latter will.
Try setting the DataField attribute based on a boolean condition on the datasource object. It appears you're binding to an ObjectDataSource. Perhaps there's a boolean condition on the class -- say it's IsHired.
Perhaps something like:
<asp:CheckBoxField headertext="mm" DataField="IsHired" />
There's a sample on the MSDN CheckBoxField article.
To add onto Nathan's answer: I would use the RowDataBound event for your GridView. Assuming you bound to a DataTable, with the interesting column being [0].
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
//Check for a data row
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Find the checkbox control by ID and set it.
((CheckBox)e.Row.FindControl("CheckBoxId")).Checked = IsItemChecked(((DataRowView)e.Row.DataItem)[0]);
}
}
The IsItemChecked function can be passed the data from the DataItem to create custom logic that passes back a boolean. Once you have the control, you can also add attributes to it. This is a powerful technique once you master it.