Nesting a ListView inside a GridView - c#

I have an ASP.NET GridView which amongst other values binds an ID to one of the columns.
Another one of the columns of this table should contain a list of items, which should be resolved by passing in the ID from the GridView.
To achieve this, I tried nesting the ListView inside the GridView, and passing the ID into the Default Parameter of an ObjectDataSource used by the ListView, but this syntax is not allowed:
<asp:TemplateField HeaderText="columnItems">
<ItemTemplate>
<asp:ListView ID="listOfItems" runat="server" DataSourceID="MyObjectDataSource >
<ItemTemplate>
<asp:LinkButton ID="MyLinkButton" Runat="Server" Text='item'></asp:LinkButton>
</ItemTemplate>
</asp:ListView>
<asp:ObjectDataSource ID="MyObjectDataSource" runat="server"
TypeName="MyTypeName.Whatever" SelectMethod="GetItems">
<SelectParameters>
<asp:Parameter Name="requestId" Type="String" DefaultValue='<%# Eval("ID")'/>
</SelectParameters>
</asp:ObjectDataSource>
</ItemTemplate>
</asp:TemplateField>
</Columns>
So how do I go about passing in the ID so I can get the list of items?

You probably need to do that in the RowDataBound event, get the ID there and then do you DB
then do something like
if(e.Row.RowType != DataControlRowType.DataRow)
{
return;
}
ListView a = (ListView)e.Row.FindControl("listOfItems");
a.datasource = // the result of your db call
a.databind();

Attach a 'OnRowDataBound' event to the GridView control to retrieve the items for the ListView for each row on the GridView (after the GridView has been bound):
e.g. On the ASPX page:
<asp:GridView id="MyGridView" OnRowDataBound="GetItems" ... > ... </asp:GridView>
In the code-behind:
protected void GetItems(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType != DataControlRowType.DataRow)
{
return;
}
// Get the ID from the GridView
var dataRowView = (DataRowView) e.Row.DataItem;
var id = dataRowView["ID"].ToString();
// Bind the supporting documents to the ListView control
var listView = (ListView) e.Row.FindControl("listOfItems");
listView.DataSource = /* Call to database to return a DataSet of items */;
listView.DataBind();
}
(As would be appropriate, I tried editing Tunisiano's post to elaborate on his answer on attaching the event to the GridView and getting the request ID, but SO editors are rejecting it for no good reason. The above code is tested and answers the question exactly).

Related

How to get a CheckBoxField from a DetailsView

I have been trying to figure this out for hours. So sad! The structure of my ascx is like
<asp:DetailsView ...>
<Fields>
.
.
<asp:CheckBoxField DataField="ThingEnabled" HeaderText="Thing Enabled"/>
.
.
.
</Fields>
</asp:DetailsView>
and the element I want is the ThingEnabled one.
Setup:
DetailsView dv = (DetailsView)sender;
CheckBoxField cbf = ????
Note that CheckBoxFields do not have ID properties, so I can't use FindControl.
Note that DetailsView uses cells on it instead of control IDs for each row it has, hence you can get CheckBoxField value using row, cell and control position like this:
// Page_Load is just an example event here, change to any event you need
protected void Page_Load(object sender, EventArgs e)
{
DetailsView dv = sender as DetailsView;
// the checkbox uses checked state as its value to be passed
// n = row/cell/control indexes where CheckBoxField has bound into, starting from 0
// e.g. dv.Rows[0].Cells[0].Controls[0] as CheckBox
bool checkboxvalue = (dv.Rows[n].Cells[n].Controls[n] as CheckBox).Checked;
}
If you still want using FindControl, use ItemTemplate wrapper element and create a CheckBox control on it (note that you may need to use a BoundField with DataField="ThingEnabled" on top of TemplateField for data binding):
<asp:DetailsView runat="server" ...>
<Fields>
...
<asp:TemplateField HeaderText="Thing Enabled">
<ItemTemplate>
<asp:CheckBox ID="ThingEnabled" runat="server" Checked="<%# Bind("ThingEnabled") %>">
</asp:CheckBox>
</ItemTemplate>
</asp:TemplateField>
</Fields>
</asp:DetailsView>
Then you can access that checkbox control using FindControl:
DetailsView dv = sender as DetailsView;
// n = row/cell indexes, starting from 0
bool checkboxvalue = (dv.Rows[n].Cells[n].FindControl("ThingEnabled") as CheckBox).Checked;
References/similar issues:
How to get value from DetailsView Control in ASP.NET?
Get the value of a BoundField from a DetailsView
Accessing DetailsView check box value
Its also possible to use linq to get any field within a DetailsView in this way.
// Page_Load is just an example event here, change to any event you need
protected void Page_Load(object sender, EventArgs e)
{
DetailsView dv = sender as DetailsView;
//using linq to get the CheckBoxField control
var field = dv.Fields.Cast<DataControlField>().Single(x => x.HeaderText == "TitleOfCheckboxField") as CheckBoxField;
}

ASP.NET Listbox inside of gridview

I have a listbox inside of a gridview which appears when you click edit, it has a list of event types which you can select multiple. I cannot figure out how to update my entity when the update button is clicked. I need to be able to update the entity collection with the selection made from the listbox inside the gridview. The gridview is using an entity datasource. Below is the list box in the gridview.
<asp:TemplateField HeaderText="Event Type">
<ItemTemplate>
<asp:Label runat="server" ID="eventTypeLabel" Text="<%#VenueExplorer.Utilities.StringUtils.convertEventsToCommaString(Container.DataItem) %>" />
</ItemTemplate>
<EditItemTemplate>
<asp:ListBox ID="eventListbox" runat="server" DataSourceID="eventTypeDataSource" DataValueField="EventTypeID" DataTextField="EventType" SelectionMode="Multiple"></asp:ListBox>
</EditItemTemplate>
</asp:TemplateField>
Is there a way I can update the entity binded to the gridview before the actual save is performed?
During the RowUpdating event of your GridView, you can capture the ListBox's selected values.
Without knowing your full markup or database structure, I can only mock up the intended code. Something like this, though you'll obviously have to modify it to suit your needs:
protected void grdView_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
ListBox eventListbox = (ListBox)grdViewName.Rows[e.RowIndex].Cells[ZeroBasedCellNumberOfTheListBox].FindControl("eventListbox");
// Retrieve the currently selected entity (row) from the database
ParentEntity yourParentEntity = from entity in DataContext.ParentEntity where entity.ID == grdViewName.Rows[e.RowIndex].Cells[IndexOfYourEntitysID].Text;
foreach (ListItem item in eventListbox.Items)
{
if (item.Selected)
{
EventType eventType = new EventType();
eventType.ID = item.Value;
eventType.Name = item.Text;
yourParentEntity.EventTypes.Add(eventType); }
}
DataContext.Commit();
}

Adding Querystring Parameter to GridView ItemTemplate

I have a gridview with a hyperlink in first column. Upon clicking the hyperlink, the user is redirected to Vendor.aspx. Now, I need to pass the consumer id (of the clicked row) as a query string to the Vendor.aspx.
What is the best method to achieve it? Is there a way in which we can handle it using markup code only?
<asp:GridView ID="grdConsumers" runat="server" AutoGenerateColumns="False"
EnableViewState="True" >
<Columns>
<asp:TemplateField HeaderText="ConsumerID" SortExpression="ConsumerID" >
<ItemTemplate>
<asp:HyperLink ID="lnkConsumerID" href="Vendor.aspx" runat="server"><%# Eval("ConsumerID")%></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="Status" DataField="Status" SortExpression="Status"></asp:BoundField>
</Columns>
</asp:GridView>
READINGS:
Set Gridview DataNavigateUrlFormatString Dynamically inside User Control(ASCX)
How do I add "&Source" to DataNavigateUrlFormatString?
Select row in GridView with JavaScript
How to bind the URL of a GridView HyperLinkField when the bound value contains a colon?
asp.net gridview DataNavigateUrlFormatString from DataSource
Try using the DataNavigateUrlFormatString
<ItemTemplate>
<asp:HyperLinkField DataNavigateUrlFields="ConsumerID" DataTextField="ConsumerID" DataNavigateUrlFormatString="Vendor.aspx?id={0}" />
</ItemTemplate>
... it will spare you Eval() and the problem with single/double quotes when putting it inside your href.
You can substitute the DataTextField if you like - I just put the ConsumerID there to be consistent with your example.
Rewrite your hyperlink in gridview in .aspx file like this:
<asp:HyperLink ID="lnkConsumerID" runat="server" Text='<%# Eval("ConsumerID")%>' />
Then in code-behind create a RowDataBound event handler:
protected void grdConsumers_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType != DataControlRowType.DataRow) return;
var hlnkhlnk = (HyperLink)e.Row.FindControl("lnkConsumerID");
if (hlnkhlnk != null)
{
hlnkhlnk.NavigateUrl = "Vendor.aspx" + "?Consumer ID=" + hlnkhlnk.Text;
}
}
Hope it helps.
You can do same using at Grid view Item Data Bound Event
protected void grdConsumers_ItemDataBound(object sender,DataGridItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
// Get your consumerId here
((HyperLink)e.Item.FindControl("Edit")).NavigateUrl = "Vendor.aspx?id=" + consumerId
}
}

How to transform a column from a gridview in a dropdownlist with 2 values to choose

I have a gridview with the following columns:
NAME|AGE|Birthday|Code
Joh 21 12.12.2 Yes/No
Currently the column code is a textbox. How can I transform it into a dropdownlist with 2 values: Yes/No so if I press edit I can choose in that cell the Value Yes or No.
Also How can I check on edit event too see if value is yes?
You can create a template field like this:
<columns>
<asp:TemplateField HeaderText="code">
<ItemTemplate>
<asp:DropDownList ID ="ddlCode" runat="server" AppendDataBoundItems="true" CssClass="DropDn1" />
</ItemTemplate>
</asp:TemplateField>
</columns>
In your rowdatabound event of the grid you will bind it if you want to bind from the database.
protected void RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList code= (DropDownList)e.Row.FindControl("ddlCode") as DropDownList;
if (code!= null)
{
//Bind the dropdownlist
}
}
To retrieve the value from the dropdown in your edit event you will do this:
string code = (row.FindControl("ddlCode") as DropDownList).Text);

Update GridView with Dropdownlist control

I am using VS2005 C#.
Currently I have a GridView, and I have changed one of my GridView control to my column name Gender, from the default TextBox to a DropDownList, which I gave the ID of the control to GenderList, and it contains 2 values, M and F.
I have a default update statement which is able to update the GridView after edit, which is the following:
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString=
"<%$ ConnectionStrings:SODConnectionString %>" UpdateCommand="UPDATE
[UserMasterData] SET [Name] = #Name, [Age] = #Age, [ContactNo]=#ContactNo,
[Address]=#Address, [Gender]=#Gender"/>
The above UPDATE query works perfectly, and now I have changed my Gender textbox to a dropdownlist, the UPDATE query gave me an error which says:
Must declare the scalar variable "#Gender".
I assume the UPDATE query couldn't find the value from my Gender column.
I tried to modify the UPDATE query to #GenderList, but it did not work as well.
Anyone knows what I should do do the UPDATE query so that my UPDATE query can find the value from my GenderList dropdownlist in my Gender column?
Thank you.
Below is my previous Gender column with a textbox control:
<asp:BoundField HeaderText="Gender"
DataField="Gender"
SortExpression="Gender"></asp:BoundField>
Below is my Gender with the dropdownlist control:
<asp:TemplateField HeaderText="Gender" SortExpression="Gender" >
<EditItemTemplate>
<asp:DropDownList ID="GenderList" runat="server" Width="50px" >
<asp:ListItem>M</asp:ListItem>
<asp:ListItem>F</asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
EDIT:
Tried implementing RowDatBound and onRowUpdating:
RowDatBound
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
DataRowView dRowView = (DataRowView)e.Row.DataItem;
if (e.Row.RowType == DataControlRowType.DataRow)
{
if ((e.Row.RowState & DataControlRowState.Edit) > 0)
{
DropDownList genderList= (DropDownList)e.Row.FindControl("GenderList");
genderList.SelectedValue = dRowView[2].ToString();
}
}
}
RowUpdating.aspx.cs
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
DropDownList genderSelect =(DropDownList)GridView1.Rows[e.RowIndex].FindControl("GenderList");
SqlDataSource1.UpdateParameters["Gender"].DefaultValue =
genderSelect.SelectedValue; --> error says not set to an instance of an object
}
If you are using SqlDataSource and updating data via it then all you have to do is to set 2 way binding for the dropdownlist GenderList.
You can set this via the designer or directly in source also
<EditItemTemplate>
<asp:DropDownList ID="GenderList" runat="server"
SelectedValue='<%# Bind("Gender") %>'>
<asp:ListItem>M</asp:ListItem>
<asp:ListItem>F</asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
notice that here 2 way binding is being used.
you need to use its selected value property, dropdown list is collection of values, but you are assigning a scalar value to your update statements.
You have to check when its in update mode, you need to get selected item value of dropdown list and use that value as parameter for update statements.
Editing with Dropdownlist in gridview
to check its in edit mode or not use like this in RowDataBound Event
if ((e.Row.RowState & DataControlRowState.Edit) > 0)

Categories

Resources