I am using a Gridview and wondering if there is way to hide a column from the Gridview but still be able to access the hidden column value.
I set visible= false for the column that I want to hide but when I try to get the value of the column, the value in the column is empty.
Thanks.
One way I have gotten values from Invisible GridView Columns is using the DataKeyNames attribute.
<asp:GridView runat="server" ID="GridView" DataKeyNames="ColName1, ColName2">
</asp:GridView>
then to access the data
var data = GridView.DataKeys[RowIndex].Values[KeyIndex]
If you're in the RowDataBound event, get the row DataItem:
if(e.Row.RowType == DataControlRowType.DataRow)
{
var dataRowView = (DataRowView)e.Row.DataItem;
var data = dataRowView["FieldName"].ToString();
}
Related
I set the sort expression for a column in a grid view. Then sort the column by clicking on Header. Upto this point fine.
However, when I select a gridView row using the select button which is autogenerated:
<asp:GridView runat="server" ID="test" DataSourceID="sourceEmployees"
AutoGenerateSelectButton="true">
After selecting a row if I sort the Column by clicking on Header, the GridView still has the old row selected. The intially selected value is lost. If i Select employeeID value 7, the 7th row remains selected even when I sort the Column in descending order, Although my employeeId value 7 has moved to different row. [ here its moved to 4th row as I have total 10 employees ]
What more I need to implement to make sure No matter the way user sorts the GridView, always the initially selected employeeID remains selected.
You need to handle everything on the code behind (selecting/deselecting the row when the index changes). Here's an example based on your set up:
<asp:GridView DataKeyNames="EmpID"
SelectedRowStyle-BackColor="Yellow" ID="test" OnSelectedIndexChanged="test_SelectedIndexChanged"
runat="server" DataSourceID="sourceEmployees" AutoGenerateColumns="False"
AutoGenerateSelectButton="true" AllowSorting="true"
OnRowDataBound="test_RowDataBound" >
Above, I added two event handlers, one for OnRowDataBound and one for OnSelectedIndexChanged. I also added the DataKey to keep track of the selected employee ID.
Now, on code behind, the for those 2 methods looks like this:
protected void test_SelectedIndexChanged(object sender, EventArgs e)
{
ViewState["key"]= test.SelectedDataKey.Value;//Keep track of selected employee by ID
}
protected void test_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var row = e.Row.DataItem as DataRowView;
if (row.Row.Field<int>("EmpID") == (ViewState["key"] != null ? (int)ViewState["key"] : -1))
{
test.SelectedIndex = e.Row.RowIndex;
//Setting the selected Index is not enough, you need to programmatically
//set the color as well. Since I used Yellow on my markup, I use the same here
e.Row.BackColor = System.Drawing.Color.Yellow;
}
}
}
We need to use the GridView.EnablePersistedSelection Property. MSDN states that
If this property is false and a row is selected, the same row is selected when a new page is displayed even though the new page has different data in it. If you set this property to true, when you display a page that has different data in it, no row is selected. If you then return to the page on which a row was selected, that row is still selected.
Setting this property to true resolved my issue.
I am new to asp.net website developer.
In my website I use GridView Control.In the GridView row i place some controls like
TextBox,DropDownList.
I can display the values in GridView.
But my requirement is ,Get the values from TextBox and DropdownList Which are existed in GridView.
Please help me to go forward..
thank you,
bye..
You need to access them by row. This code project article explains it in detail.
TextBox tb = (TextBox)gridview1.Rows[0].FindControl("idOfTextBox");
It above statement will find control in the first row of grid which has id idOfTextBox and type is textbox.
You can directly get any value of any control by casting directly, without using an extra textbox or dropdown variable.
Example:
string val = ((TextBox)gridview1.Rows[0].FindControl("TextBox_ID")).Text;
Hope it helps :)
Subscribe the RowDataBound event(this will be fired on each row available in gridview) of gridview and access like stated below,
protected void grdBillingdata_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//these controls are available inside gridview
HiddenField hdnNagetiveAmt = (HiddenField)e.Row.FindControl("hdnNagetiveAmt");
DropDownList ddlFeeType = (DropDownList)e.Row.FindControl("ddlFeeType");
TextBox txtFeeDesc = (TextBox)e.Row.FindControl("txtFeeDesc");
Button btnUpdate = (Button)e.Row.FindControl("btnUpdate");
}
}
not only text box we can get values from all the controls that used inside gridview that placed by using itemTemplate or simply a Bound field .
you need to loop for each row to get the values
foreach (GridViewRow row in grd_popup_details.Rows)
{
//get control values
}
Refference link
In a web application I am binding the data to a GridView. In the GridView some of data is repeating. I want to not display the data again and again.
For example Empid is displaying more than one time in the same column. I want to not display the empid again in that column.
You can implement the OnDataBinding event for the specific column you are using. I never use AutoGenerateColumns so having fine control of each cell is pretty simple to implement.
Eg:
// Create global in your .cs file
string _currentEmpID = string.Empty;
Define your column like:
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Literal ID="ltEmpID" runat="server"
OnDataBinding="ltEmpID_DataBinding" />
</ItemTemplate>
</asp:TemplateField>
<!-- Your other columns... -->
</Columns>
Then just implement your DataBinding event:
protected void ltEmpID_DataBinding(object sender, System.EventArgs e)
{
Literal lt = (Literal)(sender);
string empID = Eval("EmpID").ToString();
if (!empID.Equals(_currentEmpID))
{
lt.Text = empID;
_currentEmpID = empID;
}
else
{
lt.Text = string.Empty;
}
}
The RowDataBound forces you to search for controls and if changes are required in the future you have the possibility of breaking other things being modified within the event. Because of this, I prefer to use the control's DataBinding event whenever possible as it localizes functionality to only the control and gives you the flexability to swap out controls and functionality easily without the worry off affecting other things.
If you group your data by the columns you don't want to repeat before binding it to your datasource you can bind an event to RowDataBound and check if the current value equals the previous and then hide the cell.
Check this for an example.
Just add the property AutoGenerateColumns in the gridview and assign it the value of false.
AutoGenerateColumns="false"
I have a grid view which is used to show the Product details. Another thing is there is a table viz. ProductMaster. The data in the gridview is coming from this table. Now what I want is, at first time when page is loaded, only first column should be filled,which contains dropdown list containing product names. All other rows should be empty. Now when user select the Item from the dropdown list, at that time other columns should get filled repectively and other empty row should appear below filled row. Whenever the page is loaded there will be just one empty row(First column dropdown list will be filled with products)
How can I achieve this task??????
Check this article out: http://geekswithblogs.net/dotNETvinz/archive/2009/06/04/adding-dynamic-rows-in-gridview-with-textboxes.aspx
Add DropDownList inside TemplateColumn and in OnRowDataBound event fill it with the product names and instead of Click event of Button as explained in mentioned article you have to handle SelectedIndexChanged event of DropDownList, get the reference on row which contains this DropDownList and fill other columns of this row.
aspx:
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:DropDownList ID="cmbProduct" runat="server" OnSelectedIndexChanged="cmbProduct_Changed" AutoPostBack="true" >
</asp:DropDownList>
</ItemTemplate>
...
</Columns>
code behind:
protected void cmbProduct_Changed(object sender, EventArgs e)
{
DropDownList cmbProduct = (DropDownList)sender;
GridViewRow parentRow = (GridViewRow)cmbProduct.NamingContainer;
string selectedProdId = cmbProduct.SelectedValue;
/* Fetch product details & bind other columns/controls with product details */
Label lbl = (Label)parentRow.FindControl("lblProductName");
lbl.Text = "....";
/* Call AddNewRowToGrid explaied in article*/
AddNewRowToGrid();
}
I would like to be able to bulk edit all the rows for one column using a GridView control. What is the best way to do this?
If you want to update all rows with same value then show proper control(textbox/dropdown/checkbox/radio) in column header
else
show the grid column in edit mode instead of label.
See following:
http://www.codeproject.com/KB/webforms/BulkEditGridView.aspx
I guess u know this: http://msdn.microsoft.com/en-us/library/ms972948.aspx
Probably not the best, but an option is to set the primary key of your table as the DataKey of the GridView then iterate the grid and use the datakey and the edited value to update the DB. Here is an example.
<asp:GridView ID="GridView1" runat="server" DataKeyNames="ID">
<Columns>.....
foreach (var item in GridView1.Items)
{
var id = (Guid)GridView1.DataKeys[item.DataItemIndex].Value;
var txt= item.FindControl("AmountTextBox") as Textbox;
if (cb != null && id.HasValue)
UpdateRow(id.Value, txt.Text);
}