use a imageButton in GridView to select the row - asp.net

I am trying to use a image button in a grid view to select a row so that i can then use the SelectedIndexChanged function to do other things. i have tried this:
<asp:ImageButton ID="Image1" CommandName="SelectRowGrid2" runat="server" ImageUrl="~/images/select.png" />
Protected Sub GridView2_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles GridView2.RowCommand
Select Case e.CommandName
Case "SelectRowGrid2"
'some code for selecting the index?
Label1.Text = GridView2.SelectedIndex
End Select
End Sub
but it didn't even step in to the RowCommand sub when i went to debug it.

You could set GridView's AutoGenerateSelectButton to true MSDN
You could set LinkButton's CommandName to "Select" MSDN
Or you could try following:
Protected Sub ImgSelect_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs)
Dim row As GridViewRow = DirectCast(DirectCast(sender, ImageButton).NamingContainer, GridViewRow)
DirectCast(row.NamingContainer, GridView).SelectedIndex = row.RowIndex
End Sub
aspx:
<asp:TemplateField HeaderText="Select">
<ItemTemplate >
<asp:ImageButton ID="ImgSelect" OnClick="ImgSelect_Click" runat="server" />
</ItemTemplate>
</asp:TemplateField>

I have done this plenty times in c#. Maybe I can help you out.
Some things I do different than you:
I call CellContentClick opposed to RowCommand.
2. I think check to see, which cell in the row was clicked
3. Check that the row is not null
4. If it was my image button cell, get my row data
1.
private void dgv_CellContentClick(object sender, DataGridViewCellEventArgs e)
2.
if (e.ColumnIndex == dgv.Columns["btnClmn"].Index)
3.
if (dgvAllApplication.CurrentRow != null)
4.
txtName.Text = dgv.CurrentRow.Cells["App_Name"].Value.ToString();
Good Luck!

you can create on click event on the imagebutton and do whatever you need to do on that row from there
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
ImageButton img = (ImageButton)sender;
GridViewRow row = (GridViewRow)img.Parent.Parent;
//do stuff
//find label in the same row
Label lbl = (Label)row.FindControl("Label1");
}

Related

Display rows based on column values asp repeater / gridview

I am using VB.NET
I get a datatable with the following columns
ID DESC Hyperlink COUNT
The count is either 0 or 1
If the count is 0 I need to do a
NavigateUrl='<%#"~/Create.aspx?ID=" + Eval("ID")%>' Text="Create"
in the hyperlink column
I am not doing any explicit operations on the databind event.
the way i am populating the repeater is:
rptrTask.DataSource = PpltDefGrid(Trim(v))
where the function is just getting a sql table at the moment
rptrTask.DataBind()
Can someone give me the inline code on how to do this? if not any idea on how can i do this via code behind (with an Example please)? I have tried a few / Container.data methods.. but haven't been successful. Would really appreciate any help.
I am editing my answer, then in that case RowDataBound would be easy choice for you.
Modify your GridView like this:-
<asp:GridView ID="GridView1" runat="server" OnRowDataBound="GridView1_RowDataBound">
I have added "OnRowDataBound="GridView1_RowDataBound"
In your .aspx page you can write like this for hyperlink
<asp:TemplateField HeaderText="Count">
<ItemTemplate>
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="#" Text='<%#Eval("ID") %>'></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
In your .aspx.vb page write like this:-
Protected Sub GridView1_RowDataBound(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim HyperLink1 As HyperLink = DirectCast(e.Row.FindControl("HyperLink1"), HyperLink)
If DataBinder.Eval(e.Row.DataItem, "COUNT") = "0" Then
HyperLink1.NavigateUrl = "~/Create.aspx?ID=" + DataBinder.Eval(e.Row.DataItem, "ID")
End If
End If
End Sub
Hope this help.
You can use the RowDatBound() event of the gridview in code behind.
protected void rptrTask_RowDataBound(object sender, GridViewRowEventArgs e) {
if (e.Row.RowType == DataControlRowType.DataRow) {
HyperLink hl = (HyperLink)e.Row.FindControl("hyperlinkID");
if(DataBinder.Eval(e.Row.DataItem, "COUNT") == "0")
{
hl.NavigateUrl = "~/Create.aspx?ID=" + DataBinder.Eval(e.Row.DataItem, "ID");
}
}
}
I extract the logic to the variable (bShowURl) so as to enhance manintability. Also additional check is placed to ensure the hyperlink exists.
Protected Sub yourGridview_RowDataBound(sender As Object, e As GridViewRowEventArgs)
If e.Row.RowType = DataControlRowType.DataRow Then
Dim currentDataItem As yourDataItemDataType = e.Row.DataItem
Dim bShowUrl = IIF(currentDataItem.ID = 0, True, False)
If bShowUrl Then
Dim hyperlink As HyperLink = CType(e.Row.FindControl("yourHyperlinkControlId"), HyperLink)
If hyperlink IsNot Nothing Then
hyperlink.NavigateUrl = "~/Create.aspx?ID=" + currentDataItem.ID.ToString()
End If
End If
End If
End Sub

How to fire a button event from inside a repeater?

I have done my research but can't find an efficient way to do the following in VB:
Each button should fire the same event.
The button event saves every repeater item and so each event is not unique.
I am aware I can use the ItemCommand option but have not been able to get it working as desired.
ASP.NET
Inside Repeater Item
<asp:Button ID="btnSave" RunAt="Server"/>
VB.NET
Protected Sub btnSave_Click(ByVal sender As Object, ByVal e As System.EventArgs)
sqlConn.Open()
For Each Item As RepeaterItem In rpt.Items
...
Next
sqlConn.Close()
End Sub
Edit:
After some research here on SO, I found that others events than ItemCommand are not caught by Asp:Repeater, as FlySwat said on his answer. So you'll need to write your VB.NET code like this:
First, declare the ItemCommand event on your page with something like this:
Protected Sub rpt_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.RepeaterCommandEventArgs) Handles rpt.ItemCommand
If e.CommandName = "Save" Then
'Save
End If
End Sub
Then, on Asp:Button markup inside the Asp:Repeater, you must set its CommandName property like this:
<Asp:Button ID="btnSave" runat="server" CommandName="Save" UseSubmitBehavior="false"/>
Take a look here to learn more about the UseSubmitBehavior.
Try it.
When the button is inside a Repeater template, you need to add OnClick event, you can add event on ItemDataBound event of the Repeater control.
Your .aspx code will look something like this:
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<asp:Button ID="btnSave" runat="server" Text="SomeText" />
</ItemTemplate>
</asp:Repeater>
code-behind
void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == Repeater1.AlternatingItem || e.Item.ItemType == Repeater1.Item)
{
var btn = e.Item.FindControl("btnSave") as Button;
if (btn != null)
{ // adding button event
btn.Click += new EventHandler(btn_Click);
}
}
}
void btn_Click(object sender, EventArgs e)
{
//write your code
}
in vb.net
Private Sub Repeater1_ItemDataBound(sender As Object, e As RepeaterItemEventArgs)
If e.Item.ItemType = Repeater1.AlternatingItem OrElse e.Item.ItemType = Repeater1.Item Then
Dim btn = TryCast(e.Item.FindControl("btnSave"), Button)
If btn IsNot Nothing Then
' adding button event
btn.Click += New EventHandler(btn_Click)
End If
End If
End Sub
Private Sub btn_Click(sender As Object, e As EventArgs)
'write your code
End Sub

how to get value of dropdownlist which is inside a gridview on the click of a button?

I have a dropdownlist inside the gridview. Now i want when i click on a button then i can check the value of dropdownlist. I have fired rowcommand event of gridview for it but debugger is not able to go reach there..Please help me..My Code is
Protected Sub grd_Test_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles grd_Test.RowCommand
If e.CommandName = "Select" Then
End If
End Sub
my Source code is
<asp:GridView ID="grd_UnAssignProperties" runat="server" AutoGenerateColumns="False"><Columns>
<asp:TemplateField HeaderText="Assign To">
<ItemTemplate>
<asp:DropDownList ID="drp_UnAssignProp" runat="server">
<asp:ListItem Value="" >Default</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns></asp:GridView><tr><td><asp:Button ID="btn_Save" runat="server" CommandName="Select" Text="Submit" />
try this
DropDownList ddl = (DropDownList)GridView1.Rows[e.RowIndex].Cells[0].FindControl("drp_UnAssignProp");
string val = ddl.SelectedValue;
try
string val = (DropDownList)GridView1.Rows[e.RowIndex].Cells[0]
.FindControl("drp_UnAssignProp").SelectedValue;
First of all, since the button btn_Save isn't inside the GridView, clicking on it won't raise the grd_Test_RowCommand, either move the button inside GridView or you have to raise it manually like this:
Copied from asp.net forum:
Protected Sub Button1_Click(sender As Object, e As EventArgs)
Dim commandArgs As New CommandEventArgs("Command Name Here", "Your Command Argument Here")
'You can pass any row
'You can also skip the row parameter and get the row from Command Argument
Dim eventArgs As New GridViewCommandEventArgs(GridView1.Rows(0), GridView1, commandArgs)
GridView1_RowCommand(GridView1, eventArgs)
End Sub
Now regarding your original question, this is how you can get the selected value of DropDownList inside RowCommand event:
Edit: Fixed code to get the current row, for which the RowCommand event was raised
Protected Sub grd_Test_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles grd_Test.RowCommand
If e.CommandName = "Select" Then
Dim index As Integer = Convert.ToInt32(e.CommandArgument)
Dim row As GridViewRow = DirectCast(DirectCast(e.CommandSource, LinkButton).NamingContainer, GridViewRow)
Dim ddl as DropDownList = CType(row.FindControl("drp_UnAssignProp", DropDownList)
Dim selectedValue as String = ddl.Text
End If
End Sub

Dynamically add drop down lists and remember them through postbacks

I'm trying to figure out the best way to achieve this:
I need to show a drop down list when the page loads, the default selected value is nothing, or an empty element (such as "-"). When the user selects one value from the list, another drop down list is added below the first one, and so on.
My problem with this is how you make the page to remember the drop down lists created through postbacks and the values they have selected? Do I have to use some kind of array to store them or something?
Thank you very much.
EDIT: I did this example for dynamically add drop down lists and suscribe them to an event handler but the event won't fire.
EDIT 2: Changed the code because I labelled for VB.Net and posted something in C#. I update the code with some trivial improvements, but still won't fire the event :(
Private myDdlArray As New List(Of DropDownList)
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If (Session("ddl") Is Nothing) Then
Session("ddl") = myDdlArray
End If
If (Session("ddlcount") Is Nothing) Then
Session("ddlcount") = 0
End If
myDdlArray = CType(Session("ddl"), List(Of DropDownList))
Dim myDdl As New DropDownList
myDdl = New DropDownList
For Each myDdl In myDdlArray
panel.Controls.Add(myDdl)
panel.Controls.Add(New LiteralControl("<br/>"))
Next
Session("ddl") = myDdlArray
End Sub
Protected Sub btn_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn.Click
myDdlArray = CType(Session("ddl"), List(Of DropDownList))
Dim ddlCount As Integer = CInt(Session("ddlcount")) + 1
Dim newDdl As New DropDownList
newDdl.ID = String.Format("ddlNPKMaterial{0}", ddlCount)
newDdl.AutoPostBack = True
AddHandler newDdl.SelectedIndexChanged, AddressOf cbo_SelectedIndexChanged
newDdl.Items.Add("Uno")
newDdl.Items.Add("Dos")
newDdl.Items.Add("Tres")
myDdlArray.Add(newDdl)
panel.Controls.Clear()
Dim myDdl As New DropDownList
myDdl = New DropDownList
For Each myDdl In myDdlArray
panel.Controls.Add(myDdl)
panel.Controls.Add(New LiteralControl("<br/>"))
Next
Session("ddl") = myDdlArray
Session("ddlcount") = ddlCount + 1
End Sub
Protected Sub btnReset_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnReset.Click
Session("ddl") = Nothing
Session("ddlcount") = Nothing
End Sub
Protected Sub btnShow_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnShow.Click
' Insert brain here
End Sub
Public Sub cbo_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Response.Write(CType(sender, DropDownList).ID)
End Sub
Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
If (Session("ddl") Is Nothing) Then
panel.Controls.Clear()
End If
End Sub
in the aspx I have:
<form id="form1" runat="server">
<div>
<asp:Button ID="btn" runat="server" Text="Add" />
<asp:Button runat="server" ID="btnShow" Text="Tell me" />
<asp:Button runat="server" ID="btnReset" Text="Reset" />
<br />
<asp:Panel runat="server" ID="panel">
<asp:GridView runat="server" ID="grd">
<Columns>
<asp:BoundField HeaderText="Id" DataField="Id" />
</Columns>
</asp:GridView>
</asp:Panel>
</div>
</form>
I'll use OnLoad to recreate the controls, but if you're not storing the # of controls in ViewState (you could put it into Session, a HiddenField, Cookie, etc.) then you can do it in OnInit. Either way should still fire the postback event.
<asp:PlaceHolder id="phDdl" runat="server">
<asp:DropDwonList id="ddl" runat="server"
OnSelectedIndexChanged="ddl_SelectedIndexChanged" />
</asp:PlaceHolder>
<script runat="server">
int DdlIndex {
get {
object o = ViewState["_ddlIndex"];
if (o == null) {
ViewState["_ddlIndex"] = 0;
}
return (int)ViewState["_ddlIndex"];
}
set {
ViewState["_ddlIndex"] = value;
}
}
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
for (int i = 0; i < DdlIndex; i++) {
AddDropDownList(i);
}
}
void ddl_SelectedIndexChanged(object sender, EventArgs e) {
var ddl = (DropDownList)sender;
if (ddl.SelectedIndex > 0) {
AddDropDownList(DdlIndex++);
}
}
void AddDropDownList(int i) {
var ddl = new DropDownList();
ddl.Id = string.Format("ddl{0}", i);
ddl.SelectedIndexChanged += ddl_SelectedIndexChanged;
// add items
phDdls.Add(ddl);
}
</script>
You can simply have both dropdown lists exist in your asp code with only one visible on first page load. So something like...
<asp:DropDownList ID="mainDDL" Visible="true" runat="server">
<asp:ListItem Text="Elements here" Value="0" />
<asp:ListItem Text="More elements" Value="1" />
</asp:DropDownList>
<asp:DropDownList ID="dynamicDDL" Visible="false" runat="server">
<asp:ListItem Text="This is an element of the dynamic DDL" Value="3" />
</asp:DropDownList>
And then when, say the "More Elements" item selected, switch the dynamicDDL's visibility to true.
Then on each postback, on the Page_Load event, check what the value of mainDDL is. If it is 0, set dynamicDDL to have visible=true
Edit:
Okay, I took a stab at this. There is some headway in this, however, and maybe it will lead us to some clues.
To start off, we DO need an array to store this. We will need a static array of DDLs and a static integer to count our elements. These can be defined as...
Private Shared ddl_arr As DropDownList() = New DropDownList(100) {} 'max, 100 ddls.
Private Shared ddl_count As Integer = 0
Now, we'll need a panel to store our DDLs in. This is simple asp scripting, such as...
<asp:Panel ID="parentPanel" runat="server">
<asp:DropDownList ID="mainDDL" AutoPostBack="true" Visible="true" runat="server">
<asp:ListItem Text="Elements here" Value="0" />
<asp:ListItem Text="More elements" Value="1" />
</asp:DropDownList>
</asp:Panel>
So now, on our page load we will want to load any of our dropdowns that we have saved so far. This can be coded in a way such as..
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Try
If TypeOf ddl_arr(0) Is DropDownList Then
For Each ddl As DropDownList In ddl_arr
add_ddl(ddl)
Next
End If
Catch ex As Exception ' this is a bad idea, but for brevity..
End Try
End Sub
Our add_ddl method will simply add our new drop down to the parentPanel.
Protected Sub add_ddl(ByVal ddl As DropDownList)
Try
parentPanel.Controls.Add(ddl)
'add any formatting you would like after each ddl here.
Catch ex As Exception
End Try
End Sub
And finally, our method when we change the ddl. This creates a brand new ddl, gives it an id (and whatever properties you may want for it), adds it to the array, increments our counter, and adds it to the page..
Protected Sub mainDDL_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles mainDDL.SelectedIndexChanged
Dim newDDL As DropDownList = New DropDownList()
newDDL.ID = "ddlID" & ddl_count 'we will need to store a new ID for each one. So, dynamically generate this.
'continue to add properties to your ddl in this fashion...
ddl_arr(ddl_count) = newDDL
ddl_count = ddl_count + 1
add_ddl(newDDL)
End Sub
This method should definitely check for the end of the array (among other things), but lets keep things simple. This code will only add a new DDL whenever you change the index of the ORIGINAL DDL. You will need to set each newly created DDL to have a method called (performing the above instructions) whenever the selected index changes for all of those newly crafted DDLs.
Hopefully this gets you in the right direction. This was way less organized than I'd hoped, sorry!
Dynamic controls are pretty tricky to create. I would start by reading this.
Create and add the dropdowns during the Page_Init method and generate the names based on the backing data that you're gathering. When getting input from them, either read their returned values off of the page using the FindControl() method or by getting the returned value of the control from the Request.Form[]. FindControl uses the id of the control, and Requst.Name uses the client id - you can get this information using the same function you use to generate the names.
Overall, ASP.NET isn't very good at working with generated controls, but by keeping the data you're working with in a model or datastructure separate from the controls that are being generated it isn't difficult to both create the controls and retrieve the results.

Getting row index from an ImageButton click in a GridView

I have a Gridview with ImageButtons added to a column via a templatefield. I've attached a function to the "OnClick" event.
Once in this function, how can I get the index of the row that has the button that has been clicked. It appears that all I have is the mouse coordinates on the page.
Instead of looping through the rows you can use this
<asp:ImageButton runat="server" id="ibtn1" ... RowIndex='<%# Container.DisplayIndex %>'
OnClick="button_click"/>
...
protected void button_click(object sender, EventArgs e){
ImageButton ibtn1 = sender as ImageButton;
int rowIndex = Convert.ToInt32(ibtn1.Attributes["RowIndex"]);
//Use this rowIndex in your code
}
Cast the sender to an ImageButton then cast the image button's NamingContainer to a row:
VB:
Dim btn as ImageButton = CType(sender, ImageButton)
Dim row as GridViewRow = CType(btn.NamingContainer, GridViewRow)
C#:
ImageButton btn = (ImageButton)sender;
GridViewRow row = (GridViewRow)btn.NamingContainer;
Would agree with bdukes that the simplest option is to use the CommandArgument. Bind your data's unique ID number into that property, then handle the _RowCommand event.
For example:
<asp:TemplateField >
<HeaderStyle Width="20" />
<ItemTemplate>
<asp:ImageButton ImageUrl="images/icons/iCal.png" CommandArgument='<%# Eval("Event_ID") %>' ToolTip="iCal" runat="server" Height="18" Width="18" />
</ItemTemplate>
</asp:TemplateField>
Protected Sub gv_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles gv.RowCommand
e.CommandArgument 'use this value in whatever way you like
End Sub
This is very good trick.
I have another trick also.
You can try it...
protected void userGridview_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Select")
{
GridViewRow rowSelect = (GridViewRow)(((Button)e.CommandSource).NamingContainer);
int rowindex = rowSelect.RowIndex;
}
}
It's a also good method.
The easiest way that I've found is to use the Command event over the Click event, and send the item ID as the command argument.
You could also loop over the rows in the GridView and compare the ImageButton in the row to the sender argument in your Click event.

Resources