I have this BoundField in a GridView
<asp:BoundField DataField="ReportId" HeaderText="RId" Visible="false" />
But when I try to get text in that field, it returns empty.
protected void gvwReports_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "ViewSchedule")
{
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow row = gvwReports.Rows[index];
string s = row.Cells[0].Text;
}
}
but, it returns a correct value if I change BoundField's .Visible property to true
try somethink like this using client side html to hide
<style type="text/css">
.hidden
{
display:none;
}
</style>
<asp:BoundField DataField="ReportId" HeaderText="RId" HeaderStyle-CssClass="hidden" >
</asp:BoundField>
Although it's an year old question (in fact exactly an year old), here's another workaround without using CssClass.
Just after the databind, set visibility of the desired column to false.
gridview1.databind()
gridview1.columns(i).Visibile = False
This will maintain data in viewstate but will not create markup for page.
the first solution works correctly, but it was necessary add HeaderStyle to hide the header of this column
<style type="text/css">
.hidden
{
display:none;
}
</style>
<asp:BoundField DataField="ReportId" HeaderText="RId" >
<ItemStyle CssClass="hidden"/>
<HeaderStyle CssClass="hidden"/>
</asp:BoundField>
According to my knoweldge when you have made the bound field invisible then you can not access it. Try using TemplateField
I just had the same problem.
Funnily enough a DataGrid won't have that problem, it will allow you to access the data from hidden columns even though it doesn't even render them in the client, because it still adds the information of the hidden columns to the ViewState.
A GridView on the other hand simply ignore the hidden fields even if you set the EnableViewState property to true. The only way is to leave the information there for the client to hide with a style property, like display: none;.
Unfortunate really, I liked the DataGrid behaviour on that, but GridView has other advantages.
Seems that if a GridView column is marked as not visible it is not populated at run time so it returns nothing. So, I just populated the Hyperlink from the DataView that is bound to the Gridview remembering to declare the DataView as shared.
I did this in VB asp.net for a GridView that finds searched events from a calendar database.
This worked great for me!
Private Sub GridView1_RowDataBound(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
If (e.Row.RowType = DataControlRowType.DataRow) Then
Dim ThisHyperLink As HyperLink = e.Row.Cells(0).Controls(0)
Dim drvRow As DataRowView = dvFoundEvents.Item(e.Row.DataItemIndex)
EventID = drvRow("EventID")
ThisHyperLink.NavigateUrl = "<URL>?id=" + EventID
End If
End Sub
This worked for me:
If the column is a named DataKeyValue on your grid, you can cast the e.Item sent from the row as a DataGridItem and call its DataKeyValue. You'll need to convert it to Int, String, whatever but it will be there even if the column is visible=false.
At rowDataBound event you can access the field's value using something like:
(((DataRowView)e.Row.DataItem)["your_boundField_dataFieldName"]).ToString();
even if your boundfield visibility is set to false.
Related
How do I create editable gridviews with dynamic controls. The following image gives an idea.
On page load, a gridview will be shown with only a single row other than the header. The row contains two dropdownlist, two textboxes and an image button. Once I enter data in the first row, and then press the image button, a new row with these controls will be created, and so on.
How is this possible?
Gridview by default does not provide a simple way of handling the Insert operations.
You will have to perform several steps to handle this.
First of all each gridview column has to be converted to TemplateColumn(TemplateField). Then in the footer template you have to insert your controls(dropdown, textbox etc.)
<asp:TemplateField HeaderText="Item Category">
<%--Define item template--%>
<FooterTemplate>
<asp:DropDownList ID="dropDownListCategory" runat="server"></asp:DropDownList>
</FooterTemplate>
</asp:TemplateField>
...... similarly other footer templates
You have to add the onclick Event for the ImageButton.
protected void imageButtonInsert_Click(object sender, EventArgs e)
{
//Get the gridview row
GridViewRow row = (sender as Control).NamingContainer as GridViewRow;
DropDownList dropDownListCategory = row.FindControl("dropDownListCategory") as DropDownList;
///Similarly you can access the other controls here
//If you are using SqlDataSource then you can add/assign these values to the insert parameters
//Note that, you need to have insertcommand defined for the sql data source with appropreate parameters
SqlDataSource1.InsertParameters.Add("category", dropDownListCategory.SelectedValue);
//Similarly assign the other parameter values
//Call the insert method of the sql data source.
SqlDataSource1.Insert();
//If you are not using data source approach, here you can insert the data to
// database by calling sql command or other ways
//Rebind the gridview.
GridView1.DataBind();
}
This should work, when you have some rows to display in the gridview.
BIG PROBLEM : EMPTY ROWS
The above approach works when you have at least one row in the gridview. But if you do not have any rows, that is for the first time, the gridview will be empty. If the gridview data source is empty, then it does not display anything, even header,footer, rows etc.
As a initial workaround, first you need to make the header is always visible
ShowHeaderWhenEmpty="true" ShowFooter="true"
This makes sure that you have the headers all the time.
Now footer will not at all display unless and until there is some row in the gridview.
As a work around you can use EmptyDataTemplate of the gridview.
Here you need to add all your controls again, dropdownlist, textboxes etc. Not that you have to use here to make the same layout. You can use the same control ids, so that you dont need to write the codebehind again
<EmptyDataTemplate>
<tr>
<td><asp:DropDownList ID="dropDownListCategory" runat="server"></asp:DropDownList></td>
<td><asp:Button runat="server" CommandName="Insert" ID="buttonInsert" OnClick="imageButtonInsert_Click" Text="Insert" /></td>
<%--Other controls go here--%>
</tr>
</EmptyDataTemplate>
This is now good for both first time and successive load.
The next question you may have is how to bind these dropdowns. For this you need to use the RowCreated event, in which you can access the dropdowns and fill them
protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Footer || e.Row.RowType == DataControlRowType.EmptyDataRow)
{
DropDownList dropDownListCategory = e.Row.FindControl("dropDownListCategory") as DropDownList;
//similarly access the other controls and bind them
}
}
For Doing this use can use Dynamic table at client side. where you can create whole table dynamically and also apply styling that can look like grid view. for Styling use can use JQuery DataTables which provice much more controls.
And also by using JQuery DataTables or JQuery Code you can also add rows dynamically at client side.
I have a GridView and one of the columns has a TemplateField using a LinkButton (ButtonField)
I can get the value of a specific cell in my Grid Just fine. Using:
GridViewRow row = GridView1.SelectedRow;
lblSalesmanCustomers.Text = row.Cells[2].Text;
I then display the text from that cell in a Label.
However I cannot get this to work with a ButtonField Template. It only works with a non Template column.
How can I get the value of a specific cell in a column that is using a ButtonField / TemplateField?
EDIT: This is My Button Field Code inside my GridView:
<asp:ButtonField DataTextField="Customer" HeaderText="Customer" ButtonType="Link" CommandName="Select" />
Also, this is happening in this event:
protected void gvManagerCustomers_SelectedIndexChanged(object sender, EventArgs e)
See if var Button = row.Cells["Customer"].Controls[0]; would retrieve the button you need.
You might need to cast it to the correct type.
I know there are issues with hyperlinkfield and buttonfield but there is a work around. Say you are binding buttonfield text based on a column called ButtonNames, and in that column you have all your names, such as "button bob", "button jerry" etc. In your GridView, add an invisible column as your very first column and bind its value as ButtonNames. You make it invisible by setting one of the visibility properties. Forgot what it was from top of my head. Then, when you want to get the text for the buttonfield simply get the data from that invisible column instead Same applies to hyperlinkfiends.
EDIT: here's some code.
<asp:BoundColumn ItemStyle-HorizontalAlign="Left" DataField="ButtonNames" SortExpression="ButtonNames" HeaderText="TriageId" Visible="false" ReadOnly="true"></asp:BoundColumn>
Then you retrieve it via string s = e.Item.Cells[0].Text where e is a DataGridCommandEventArgs or something to that nature.
There will be a controls collection in the cell - you may be able to access it there.
Though a simpler way would be to use something like:
Label l = row.FindControl("myControlId");
EDIT: true the exact approach above does not work - but you can use the controls, the following does work, note that what we are doing here is pretty much rife with bad practices (but then we are using a GridView for convenience sake after all).
protected void gvManagerCustomers_SelectedIndexChanged(object sender, EventArgs e)
{
var x = ((sender as GridView).SelectedRow.Cells[0].Controls[0] as LinkButton).Text;
}
In order to figure this out set up a debug environment and breakpoint in the handler method then drill down through the class hierarchy. The debugger is our friend ;)
EDIT just to mention the obvious - the column is hard coded here - you will probably have to change it.
I would like to change the text of the autogenerated "select" column in an ASP.NET GridView control. The text needs to be changed to the value of a DataField.
I suspect that there is a very logical way to do this but I am missing it.
I am able to add controls and data via the pre-render event but is there an easier better way?
Use the TemplateField and place into it buttons or linkbuttons with appropriate CommandName property: ButtonField.CommandName Property
You may set this button text using DataBinder.Eval method.
The easiest way I found to do this is after the calling DataBind() just before the gridview control is displayed.
foreach (GridViewRow row in gvAgreementList.Rows)
{
LinkButton lb = (LinkButton) row.Cells[0].Controls[0];
lb.Text = "Edit";
}
after <column> write this:
<asp:CommandField ShowSelectButton="True" SelectText="Save" />
and remove AutoGenerateSelectButton="True" from Gridview attribute.
First remove auto generated select then go to GridView tasks.. top right Button of GridView and then click on commandfields -> Select then edit SelectText.
(Edited answer of ShaileshK with some changes)
Go to GridVIew tasks.. top right Button of GridView and then click on edit columns
In selected fields section Click on select field. change the value of select text.
done.
I have a dataGrid(not dataGridView) in which i need to add Checkbox dynamically at the first column. How can i do this.?
In the ItemDataBound event, which fires for each row of the DataGrid, you could dynamically add a control to the first cell. Easier to use a TemplateColumn, but if you want to do it dynamically as you asked, this is how I'd do it.
private void DataGrid1_ItemDataBound(object sender,
System.Web.UI.WebControls.DataGridItemEventArgs e)
{
if ((e.Item.ItemType == ListItemType.AlternatingItem) ||
(e.Item.ItemType == ListItemType.Item))
{
CheckBox chk = new Checkbox();
e.Item.Cells[0].Controls.Add(chk);
}
The following woprks with a GridView, and I believe that it's also the same for a DataGrid.
Just add a Template Column. (You can do that in source or via the GUI). Then add a checkbod to the ItemTemplate:
<Columns>
<asp:TemplateField>
<HeaderTemplate>
Retry
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
ps. Might want to consider dropping in a GridView if you're on 2.0+
I don't believe you can add them to the first column dynamically if the datagrid already has columns, because it would just append the new column to a datagrid by using the Add method, making it the last column:
CheckBoxColumn checkCol = new CheckBoxColumn();
DataGrid1.Columns.Add(checkCol);
but to add them dynamically you could either follow thse steps at CodeProject Adding a CheckBox column to your DataGrid
or
If you still want the look of them being in the first column, then you can just create them in your client side code and set their visibile attribute to false and when you conditions are met in code behind then set the attribute to true, which gives the idea that it was crated dynamically
I have a report page that can display two different reports. So I have a GridView with no columns on my aspx page. I am adding 4 BoundFields to the GridView in the button click event handler. The first column is the one I need to set the width of for one of the reports (the code I'm using to add this column is below).
gvReport.Columns.Clear();
BoundField bf1 = new BoundField();
...
if (ddReportType.SelectedValue == "full") {
bf1.HeaderText = "Facility";
bf1.DataField = "Facility";
bf1.ItemStyle.Wrap = true;
bf1.ItemStyle.Width = 150;
bf1.Visible = true;
gvReport.Columns.Add(bf1);
...
The problem is there is one row that has a SHA512 hash in this column. Since there is no space in the middle of it, the gridview won't wrap it (I think that's what is happening, anyway)! So I thought I'd catch this column in the OnRowDataBound event and add a space in the middle of the hash so it will wrap, but I can't figure out how to reference the BoundField. There's no ID property. Does anyone have a suggestion? Either on how to reference the BoundField, or another way to get this to display nicely?
I had the columns in the aspx file originally and tried using:
gvReport.Columns[0].ItemStyle.Width = 150;
gvReport.Columns[0].ItemStyle.Wrap = true;
but that didn't work either. This is very frustrating!
So we went with Plan C. I never did figure out how to reference the BoundField. We got around that problem by creating two GridViews in the markup and just changing which one is visible. To solve the problem of the text that won't wrap, we're catching it in the OnRowDataBound event handler and checking the length of the text. We just insert a space in the middle, and voila! It wraps!
The BoundField is a wrong thing. It is more like a definition. Later, when binding or creating rows, you are dealing with rows, cells, and data items.
You could do something like this:
protected void grid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string value = e.Row.Cells[1].Text;
if (!string.IsNullOrEmpty(value))
e.Row.Cells[1].Text = value.Insert(value.Length / 2, " ");
}
}
where Cell[1] is the column containing long values. In the same place, you could use e.Row.DataItem to get actual data, but then you'd need to know its type.
You could create a template field and bind to an expression or use its child's data bound event to do the same.
Also, if you were using a DataSet, you could set up calculated field and bind to it. Anyway...