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.
Related
What should go inside this method? I have a grid displaying results from my SQL Query --- but the grid never populates. The grid is created using HTML and this is how my OnDataItemBound event reads....but what should go here?
protected void dtgfourfiveseven_OnItemDataBound(object sender, DataGridItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
{
}
}
This is my html I am using to create the grid
<asp:DataGrid runat="server" ID="dtgfourfiveseven" AutoGenerateColumns="false" CssClass="DataGrids"
GridLines="Both" ShowFooter="true" Visible="false" OnItemDataBound="dtgfourfiveseven_OnItemDataBound">
<ItemStyle CssClass="row" />
<FooterStyle CssClass="DataGridFooters" />
<HeaderStyle CssClass="DataGridHeaders" />
<Columns>
<asp:BoundColumn DataField="Employee Name" HeaderText="Employee Name" ItemStyle-Width="100px"></asp:BoundColumn>
<asp:BoundColumn DataField="Eligible For Rehire" HeaderText="Eligible For Rehire" ItemStyle-Width="50px"></asp:BoundColumn>
<asp:BoundColumn DataField="Not Eligible For Rehire" HeaderText="Not Eligible For Rehire" ItemStyle-Width="50px"></asp:BoundColumn>
</Columns>
In my opinion the OnDataItemBound event is not what is preventing the data from displaying. Either your query is returning 0 rows, or you are not binding the query results to the grid. Per MSDN this is what you use the OnDataItemBound event for:
Use the ItemDataBound event to customize the DataGrid control. The ItemDataBound event allows you to access the data before the item is displayed in the control.
An common example of this would be manipulating the data that is returned from your query. I.E. formatting a column to currency.
Thank you for providing the code on how you actually generate your grid through html, but please also provide additional code. Showing how you are actually executing your SQL Query, and how you are actually binding the query results to the grid will allow us to further assist in troubleshooting what is the culprit here.
EDIT ---
A second thought that comes to mind, that may be a quick thing to check is, are you setting the grid.visible = false and not setting it to true later on so the grid is showing your data it is just not showing on the page?
I am using Datagrid with a hyperlink column.
<asp:DataGrid ID="dg" runat="server" AllowSorting="True" Font="Trebuchet MS, 14.25pt" Width ="880px"
AutoGenerateColumns="false" ForeColor="Black" AlternatingItemStyle-BackColor="LightGray"
OnItemDataBound="dgdatabound" EnableViewState="true">
<HeaderStyle CssClass="GridHeader" />
<ItemStyle CssClass="GridItem" />
<AlternatingItemStyle CssClass="GridAltItem" />
<PagerStyle VerticalAlign="Middle" />
<Columns>
<asp:HyperLinkColumn DataTextField ="BugId" HeaderText="BugId" HeaderStyle-Width ="60"
DataNavigateUrlField ="BugId"
DataNavigateUrlFormatString="SOME URL?USER"
HeaderStyle-BackColor="AliceBlue" />
</Columns>
From the above code, How can I pass 'USER' value from Session.
As of now i have tried with:
DataNavigateUrlFormatString="SOME URL?USER =<% Session["username"]%>"
but it didnt worked :(
You can't use ASP.NET inline expressions in properties of server controls.
See this MSDN artcle:
Remember that the displaying expression cannot be used in the
attributes of server controls. This is because the .NET Framework
directly compiles the whole expression instead of the displaying
content as the value to the attribute.
You will need to set this value in your code page, if you absolutely need to get it from the Session.
It's kind of hacky, but you could do it like this (probably in your Page_Load):
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
string yourURL = "SOME URL?USER=" + Session["username"].ToString();
dg.Columns[0].DataNavigateUrlFormatString = yourURL;
}
}
Note: the only reason I say "kind of hacky" is that you have to hardcode the column ordinal (number), which is fragile (if your column order changes).
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.
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"
I am creating a GridView/DetailsView page. I have a grid that displays a bunch of rows, when a row is selected it uses a DetailsView to allow for Insert/Update.
My question is what is the best way to link these? I do not want to reach out to the web service again, all the data i need is in the selected grid view row. I basically have 2 separate data sources that share the same "DataObjectTypeName", the first data source retrieves the data, and the other to do the CRUD.
What is the best way to transfer the Selected Grid View row to the Details View? Am I going to have to manualy handle the Insert/Update events and call the data source myself?
Is there no way to link these two so they use the same data source ?
<asp:GridView ID="gvDetails" runat="server" DataKeyNames="ID, Code"
DataSourceID="odsSearchData" >
<Columns>
<asp:BoundField DataField="RowA" HeaderText="A" SortExpression="RowA" />
<asp:BoundField DataField="RowB" HeaderText="B" SortExpression="RowB" />
<asp:BoundField DataField="RowC" HeaderText="C" SortExpression="RowC" />
....Code...
<asp:DetailsView ID="dvDetails" runat="server" DataKeyNames="ID, Code"
DataSourceID="odsCRUD" GridLines="None" DefaultMode="Edit" AutoGenerateRows="false"
Visible="false" Width="100%">
<Fields>
<asp:BoundField DataField="RowA" HeaderText="A" SortExpression="RowA" />
<asp:BoundField DataField="RowB" HeaderText="B" SortExpression="RowB" />
<asp:BoundField DataField="RowC" HeaderText="C" SortExpression="RowC" />
...
The standard way to do it would be to have the selected item of the griview be a control parameter to the objectdatasource you have wired up to the detailsview. I would probably not worry too much about the overhead of retreiving data that you already have unless you are catering to users with such slow connections that you want to avoid roundtrips to the webserver at all costs.
If you really want to avoid that thenyou could pull the data out of the gridview using javascript/jquery and then do your inserts/updates via ajax calls. It would require lots more coding though.
This is a really old thread, but in case anyone came here looking for an answer like I did, a simple solution is to add this function to your code:
(Note that this only works if the rows in your GridView match the entries in your DetailsView.)
protected void GridView1_OnSelectedIndexChanged(object sender, EventArgs e)
{
DetailsView1.SetPageIndex(GridView1.SelectedIndex);
}
And modify the GridView and DetailsView to include these settings:
<asp:GridView ... OnSelectedIndexChanged="GridView1_OnSelectedIndexChanged" ... >
<asp:DetailsView ... AllowPaging="True" ... >
This will make the selected page in the DetailsView match the selected index in the GridView.
You can hide the paging options in the DetailsView properties if you dont want users to navigate using paging in the DetailsView.