Gridview template radiobuttonlist SelectedInxedChanged, Getting the row the list was in when it fired - asp.net

I have a Gridview in which one of the template fields has a radiobuttonlist and a dropdownlist. How can I access the row that the radiobuttonlist is in on the SelectedIndexChanged event, so I don't end up updating all of the dropdownlist inside the that template field of the gridview. I don't have any code currently but any help would be greatly appreciated

<asp:TemplateField HeaderText="Column with ListControls" >
<ItemTemplate>
<asp:DropDownList ID="DropdownList1" OnSelectedIndexChanged="SomethingChanged" AutoPostBack="true" runat="server" >
<asp:ListItem Text="1"></asp:ListItem>
<asp:ListItem Text="2"></asp:ListItem>
</asp:DropDownList>
<asp:RadioButtonList ID="RadioButtonList1" OnSelectedIndexChanged="SomethingChanged" AutoPostBack="true" runat="server">
<asp:ListItem Text="1"></asp:ListItem>
<asp:ListItem Text="2"></asp:ListItem>
</asp:RadioButtonList>
</ItemTemplate>
</asp:TemplateField>
Codebehind VB.NET:
Protected Sub SomethingChanged(ByVal sender As Object, ByVal e As EventArgs)
'in this example this handler is used for both, Dropdownlist and RadiobuttonList'
Dim listControl = DirectCast(sender, ListControl)
Dim row = DirectCast(listControl.NamingContainer, GridViewRow)
Dim item = listControl.SelectedItem
'with FindControl on the row you could also find controls in other columns...'
End Sub
C#:
protected void SomethingChanged(object sender, EventArgs e)
{
//in this example this handler is used for both, Dropdownlist and RadiobuttonList
var listControl = (ListControl)sender;
var row = (GridViewRow)listControl.NamingContainer;
var item = listControl.SelectedItem;
//with FindControl on the row you could also find controls in other columns...
}

Related

I can't access the ID nested inside the ListView <itemtemplate>

I am trying to grab the value of the checkbox every time a user checks it using the following markup:
<!---- <asp:CheckBoxList ID="CheckboxWattage" runat="server" RepeatColumns="1" CellSpacing="-1" RepeatDirection="Vertical" RepeatLayout="Flow" TextAlign="Right" Width="300px">
<asp:ListItem text="" value=""></asp:ListItem>
</asp:CheckBoxList>--->
<asp:Listview id="filterListView" runat="server" DataSourceID="" onitemdatabound="filterListView_ItemDataBound" >
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" value='<%#DataBinder.Eval(Container.DataItem,"UDF_WATTAGE") %>' runat="server"/>
<asp:label ID="LabelValue" AssociatedControlID="CheckBox1" runat="server" text='<%#Eval("UDF_WATTAGE") %>' ></asp:label>
<asp:label Style="font-size:12px; font-style: italic;" ID="countLabel" runat="server" text='<%# "(" + DataBinder.Eval(Container.DataItem,"CountofUDF_WATTAGE") +")" %>' ></asp:label>
</br>
</ItemTemplate>
</asp:Listview>
<asp:Button id="wattagebtn" text="Apply" class="btn btn-danger" style="float:right;" onclick="wattageApply_Click" runat="server"></asp:Button>
<asp:Label ID="Label1" runat="server" Text="hi"></asp:Label>
</div>
</div>
code behind update! I think I was able to grab the CheckBox1 ID. how can I grab the checkbox value? When checked?
I will update once I find the solution for anyone that's having the same issue.
UPDATEEE FOUND THE SOLUTION. i had to put if(!IsPostBack){ }
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
dapter.Fill(ds);
filterListView.DataSource = ds;
filterListView.DataBind();
}
protected void filterListView_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
}
}
protected void wattageApply_Click(Object sender, System.EventArgs e)
{
foreach (ListViewItem item in filterListView.Items)
{
CheckBox cb = item.FindControl("CheckBox1") as CheckBox;
if (cb.Checked == true)
{
string ch;
Label1.Text = cb.Text;
}
else
{
Label2.Text = cb.Text;
}
}
<asp:ListView ID="ListView1" runat="server" DataSourceID="">
<ItemTemplate>
<div>
<asp:CheckBox ID="CheckBox1" runat="server"
OnCheckedChanged="ListViewItemCheckChanged"
Text='<%#DataBinder.Eval(Container.DataItem,"UDF_WATTAGE") %>' />
.
.
.
</div>
</ItemTemplate>
</asp:ListView>
Code Behind (VB.NET):
Protected Sub ListViewItemCheckChanged(sender As Object, e As EventArgs)
Dim cb As CheckBox = sender
// at this point the variable cb contains the user selected checkbox
End Sub
This will allow you to examine the last Checkbox the user clicked
Keep in mind there will be a postback on each click.
This will give you what you are asking for but is probably not the best interface experience for the user.
Typically when presented with multiple check boxes you allow all the user selections and then process the selections with one postback via some submit style button. This would require:
Looping through the ListView's Item Collection,
For each ListViewDataItem find each CheckBox via FindControl("CheckBox1")
Check for CheckBox1.Checked() and act accordingly
Addendum: How to Loop through ListView Items (VB.NET):
Private Sub Button1_Click(sender As Object, e As System.EventArgs) Handles Button1.Click
Dim cb As CheckBox
For Each lvi As ListViewDataItem In ListView1.Items
cb = lvi.FindControl("CheckBox1")
If cb.Checked Then
...
Else
...
End If
Next
End Sub
Addendum: A word about Checkboxes:
An ASP CheckBox doesn't have a value per se. It's "value" is the Boolean "cb.Checked". But there are two ways you can associate a value with CheckBox
1) If the value is not a security issue and not particulary lengthy you can add an Attribute in the ListView ItemDataBound event
Private Sub ListView1_ItemDataBound(sender As Object, e As ListViewItemEventArgs) Handles ListView1.ItemDataBound
If e.Item.ItemType = ListViewItemType.DataItem Then
Dim drv As DataRowView = e.Item.DataItem
Dim cb As CheckBox = e.Item.FindControl("CheckBox1")
cb.Attributes("some-legal-html-attribute-name") = drv("Some_dataset_field")
End If
End Sub
You are doing something similar with this in your aspx:
<asp:CheckBox ID="CheckBox1" runat="server"
value='<%#DataBinder.Eval(Container.DataItem,"UDF_WATTAGE") %>'/>
the above should render to something like this:
<input id="ListviewMangledprefix_CheckBox1" type="checkbox"
value="[value of UDF_WATTAGE FIELD]" />
Inspect the field in the rendered browser page and see if the "value" attribute is being rendered. If so you should be able to access it in the code behind as:
Dim wattage as String = cb.Attributes("value")
2) Better and more secure would be to implement and use ListView1.DataKeys. But this is a much more extensive topic that you should research when you have time

pass ID value to OnCheckedChange event in code behind

I have a gridview that has one checkbox for each row of data.
When the checkbox is checked or unchecked, I need to update a bit flag in my database.
I'm trying to use the OnCheckedChanged event.
It does fire, however I am getting a null error which has to do with an ID.
My problem is, I'm not quite sure how to get the needed ID to the OnCheckedChanged event code.
I need this ID to update the appropriate row in my database.
I found a few relavent questions on StackOverflow but none of the supplied answers really helped me out.
Thanks!
My gridview code:
<asp:GridView ID="gvlisting" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField HeaderText="Item Is Ready">
<ItemTemplate>
<asp:CheckBox ID="isReady" runat="server" AutoPostBack="true" OnCheckedChanged="isReady_CheckedChanged" Checked='<%#isReady(CInt(Eval("isReady")))%>'/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Item Name">
<ItemTemplate>
<asp:Label ID="itemName" runat="server" Text='<%#cleanString(Eval("itemName").ToString())%>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
code behind:
Public Sub isReady_CheckedChanged(ByVal sender As Object, ByVal e As EventArgs)
Dim box As CheckBox = DirectCast(sender, CheckBox)
If box.Checked = True Then
'custom code for executing an SQL UPDATE statement
db.ExecuteNonQuery(AddIsreadyFlag, New SqlParameter("#itemID", Me.ID))
Else
db.ExecuteNonQuery(RemoveIsreadyFlag, New SqlParameter("#itemID", Me.ID))
End If
End Sub
Me.ID is the ID of the Page since Me is the current page-instance.
You could add another template-field with the ID:
<asp:TemplateField HeaderText="Item-ID" Visible="false">
<ItemTemplate>
<asp:Label ID="itemID" runat="server" Text='<%# Eval("itemID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
Now you can use the NamingContainer to get the row and FindControl to get the label:
Public Sub isReady_CheckedChanged(ByVal sender As Object, ByVal e As EventArgs)
Dim box As CheckBox = DirectCast(sender, CheckBox)
Dim row = DirectCast(box.NamingContainer, GridViewRow)
Dim itemID = DirectCast(row.FindControl("itemID"), Label).Text
If box.Checked = True Then
'custom code for executing an SQL UPDATE statement
db.ExecuteNonQuery(AddIsreadyFlag, New SqlParameter("#itemID", itemID))
Else
db.ExecuteNonQuery(RemoveIsreadyFlag, New SqlParameter("#itemID", itemID))
End If
End Sub
You can also try to add a custom attribute in the OnDataBinding event and retrieve the value in de CheckChanged event.
protected void chkEnabled_DataBinding(object sender, EventArgs e)
{
CheckBox chk = (CheckBox)sender;
string id = Eval("Id").ToString();
chk.Attributes.Add("data-id", id);
}
protected void chkEnabled_CheckedChanged(object sender, EventArgs e)
{
CheckBox chk = (CheckBox)sender;
string id = chk.Attributes["data-id"];
}
Add the ID column to the grid, then if needed set it's visible property to false.
You can get the Gridview's selected row then get cell the value for ID column (the column does not need to be visisble, but it needs to exist in the grid).
var someVar = gvlisting.SelectedRow.Cells[0].Text; //change 0 to correct column
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.selectedrow(v=vs.110).aspx
You may need to do this in a SelectedIndexChanged but i doubt that, if that is the case you can easily get the data from the cell using the above or findcontrol like...How to find control in TemplateField of GridView?

Can't find dropdown list in RowDataBound event

I'm following this example http://www.codeproject.com/KB/webforms/Editable_GridView.aspx to build an editable GridView control.
I have this code in my GridView:
<asp:TemplateField HeaderText="Negócio">
<ItemTemplate>
<asp:Label ID="lblNegocio" runat="server" Text='<%# Eval("Negocio") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlNegocio" runat="server" />
</EditItemTemplate>
<FooterTemplate>
<asp:DropDownList ID="ddlNewNegocio" runat="server" />
</FooterTemplate>
Now, I'm trying to fill the dropdown in the EditItemTemplate with some dynamic values just as the example says, in the RowDataBound Event of the grid. But when I do this, the FindControl method always returns Nothing:
Protected Sub gdvRegraRotationDefault_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gdvRegraRotationDefault.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim ddlNegocio As DropDownList = e.Row.FindControl("ddlNegocio")
End If
End Sub
If I can't find the Dropdown I can't load the values in it and when I'm going to edit de entry it will be empty.
Can someone help me?
Thank you (:
Please use the RowEditing-Event, as your DropDownList should only be shown when clicking Edit.
But first, you have to bind the GridView newly as the GridView now needs to render different controls for the edit row:
protected void gdvRegraRotationDefault_RowEditing(object sender, GridViewEditEventArgs e)
{
gdvRegraRotationDefault.EditIndex = e.NewEditIndex;
gdvRegraRotationDefault.DataBind();
GridViewRow row = gdvRegraRotationDefault.Rows[e.NewEditIndex];
DropDownList ddl = row.FindControl("ddlNegocio") as DropDownList;
//now do databinding for DropDownList
}
The FindControl always return null because when your in the RowDataBound event you can get the label only.
If you want to fill the DropDownList when you click the edit button on the grid, then you have to use the GridViewRowEditing event.
In the RowDataBound event, simply add the following conditional:
if (myGridView.EditIndex == e.Row.RowIndex)
{
//do work
}

Accessing Controls Inside ASP.NET View Controls (Event Handling)

If I have the following ListView, how can I attach a SelectedIndexChanged event listener to the DropDownList so I can perform a command on the respective object? Imagine I have a list of new users and I want to add them to a usergroup by selecting the group from the DropDownList.
<asp:ListView ID="NewUsers" runat="server" DataSourceID="NewUsersSDS" DataKeyNames="ID">
<LayoutTemplate>
<asp:Table ID="groupPlaceholder" runat="server"><asp:TableRow></asp:TableRow></asp:Table>
</LayoutTemplate>
<GroupTemplate>
<asp:TableCell ID="itemPlaceholder" runat="server"></asp:TableCell>
</GroupTemplate>
<ItemTemplate>
<asp:Table ID="NewUsersTable" runat="server" Width="32%" CssClass="inlineTable">
<asp:TableRow>
<asp:TableCell Width="100px"><%# Eval("FullName").ToString.Trim()%></asp:TableCell>
<asp:TableCell>
<asp:HiddenField ID="RowIndex" runat="server" Value="<%# Container.DisplayIndex %>" />
<asp:DropDownList ID="UserGroupSelect" runat="server" DataSourceID="UserGroupSelectSDS" DataValueField="ID" DataTextField="UserGroup"
OnSelectedIndexChanged="UserGroupSelect_SelectedIndexChanged" AutoPostBack="True">
</asp:DropDownList>
</asp:TableCell>
</asp:TableRow>
</asp:Table>
</ItemTemplate>
</asp:ListView>
I've been having issues accessing controls inside of __View controls. I read in a few places that you could access them by NewUsers.FindControl([ControlID as String]) but this doesn't seem to be working for me. I guess this is what's called a dynamic control? Not really sure, feeling a bit lost.
As always, your help is greatly appreciated. ;)
Additional Info / Code
'Now working code, thanks to James :)
Protected Sub ItemBind(ByVal sender As Object, ByVal e As ListViewItemEventArgs) Handles NewUsers.ItemDataBound
Dim lv As ListView = DirectCast(sender, ListView)
If e.Item.ItemType = ListViewItemType.DataItem Then
lv.DataKeys(e.Item.DataItemIndex).Value.ToString() 'get the datakey
End If
End Sub
Protected Sub UserGroupSelect_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
Dim RowIndex As Integer = CInt(DirectCast(DirectCast(sender, DropDownList).Parent.FindControl("RowIndex"), HiddenField).Value)
Dim pk As Integer = CInt(NewUsers.DataKeys(RowIndex)("ID"))
Try
MessageBox("Update key " + pk.ToString, "Update Key") 'Custom js "alert" box function
Catch ex As Exception
MessageBox("Something went wrong, is the update key empty?")
End Try
End Sub
To access controls in a ListView (or any databound control), you need to use FindControl on the item/row:
ListViewItem item = ListView1.Items[0];
if (item != null)
{
DropDownList ddl = item.FindControl("DropDownList1") as DropDownList;
if (ddl != null)
{
string value = ddl.SelectedValue;
}
}
As for attaching a SelectedIndexChanged event, you can do it like this:
<ItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server"
AutoPostBack="true"
OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged">
</asp:DropDownList>
<asp:HiddenField ID="HiddenField1" runat="server" Value='<%# Container.DisplayIndex %>' />
</ItemTemplate>
Code-behind:
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
int rowIndex = Convert.ToInt32(((HiddenField)((DropDownList)sender).Parent.FindControl("HiddenField1")).Value);
ListViewItem item = ListView1.Items[rowIndex];
if (item != null)
{
//your logic here
}
}
To retrieve a datakey:
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
int rowIndex = Convert.ToInt32(((HiddenField)((DropDownList)sender).Parent.FindControl("HiddenField1")).Value);
int pk = (int)ListView1.DataKeys[rowIndex]["PrimaryKey"];
}

ASP.NET - GridView - How to programmatically add and read new controls to the cell?

Here is the setup:
I programmatically populate my gridview using LINQ to SQL query. Then I enter the edit mode and want to replace some standard TextBox controls with DropDownLists like this:
'excerpt from GridView1_RowEditing
Dim ddlist1 As New DropDownList
Dim res1 = From items1 In mydb.Items
Select items1.Col10
ddlist1.DataSource = res1
ddlist1.DataBind()
GridView1.Rows.Item(0).Cells(1).Controls.Add(ddlist1)
At this moment I have my gridview showing standard textbox control and new DDList control (in the Column 1).
The problem is -- I cant read the value from DDList in the RowUpdating method. It seems like DDList control is not in the GridView1.Rows.Item(0).Cells(1).Controls collection.
RowUpdating method sees only standard TextBox control and can read it's value.
Any suggestions are welcome. I just don't understand something here :(
Use TemplateField, and then you can locate your dropdown using FindControl
<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server">
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
...
Protected Sub GridView1_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles GridView1.RowUpdating
Dim ddl = CType(GridView1.Rows(e.RowIndex).Cells(1).FindControl("DropDownList1"), DropDownList)
End Sub

Resources