How to fire an event when user change a dropdownlist inside an asp.net listview? - asp.net

i have a Listview that i use like a gridview. inside the itemtemplate i have only a 'modifyble' field, a dropdownlist.
I would like to fire a 'Save' event when user change the dropdownlist. I know i have to set up the autopostback = true of the dropdownlist but i don't know how to fire the event because visual studio don't allow me to create the 'on change event' of the dropdownlist when it is inside a listview.
This is my code example
<asp:ListView ID="lvDmr" runat="server" DataSourceID="dsDmr" DataKeyNames="id">
<ItemTemplate>
<table style="width: 100%;" cellspacing="0" cellpadding="8">
<tr style="width: 100%;">
<td class="colonna-griglia" style="width: 5%;">
<%# Convert.ToDateTime(Eval("data_rilevazione")).ToString("d") %>
</td>
<td class="colonna-griglia">
<%# Eval("rivista")%>
</td>
<td class="colonna-griglia">
<asp:DropDownList runat="server" ID="myComboBox" DataSourceID="dsAgenti" DataTextField="customer"
DataValueField="customer" Width="150px" AutoPostBack="true">
</asp:DropDownList>
</td>
...
....
</asp:listview>

You may not get this in designer view, but if you directly add event handler it will definitely work. Following are code snippet for this.
Add OnSelectedIndexChanged="myComboBox_SelectedIndexChanged" to myComboBox.
<asp:DropDownList runat="server" ID="myComboBox" DataSourceID="dsAgenti" DataTextField="customer"
DataValueField="customer" Width="150px" AutoPostBack="true" OnSelectedIndexChanged="myComboBox_SelectedIndexChanged">
</asp:DropDownList>
Next in serverside , use following for event handler.
protected void myComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList ddlListFind = (DropDownList)sender;
ListViewItem item1 = (ListViewItem)ddlListFind.NamingContainer; // item1, is current row of Listview, which hold the dropdownlist that caused postback.
}
More help - http://forums.asp.net/t/1357900.aspx?SelectedIndexChanged+of+a+DropDownList+which+is+inside+a+ListView

protected void dropdownlist1_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList ddl = (DropDownList)sender;
ListViewItem dst = (ListViewItem)ddlListFind.NamingContainer;
DropDownList gddl = (DropDownList)dst.FindControl("dropdownlist1");
HiddenField hid_msg = (HiddenField)item1.FindControl("hidmsg");
hid_msg.Visible = true; hid_msg.Value = "Dropowntext : " + gddl.SelectedItem.Text.Trim() + " and value of dropdown is : " + gddl.SelectedItem.Value.Trim();
}
Or visit this link for more detail:
https://forums.asp.net/t/1357900.aspx?SelectedIndexChanged+of+a+DropDownList+which+is+inside+a+ListView

Related

wont display drop down

<form>
<asp:Repeater id="rptComments" runat="server">
<HeaderTemplate>
<table class="detailstable FadeOutOnEdit">
<tr>
<th style="width:200px;">Answers</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<th style="width:200px;"><asp:DropDownList ID="dropDownForChecklistAnswers" runat="server" /></th>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
<asp:Button id="button" text="Submit" OnClick="Page_Load" runat="server" />
</FooterTemplate>
</asp:Repeater>
</form>
Code Behind:
List<Checklist_Record_Choice> CLRC =
(from choice in db.Checklist_Record_Choices
select choice).ToList();
dropDownForChecklistAnswers.DataSource = CLRC;
DropDownList1.DataTextField = Text;//Text being the name of column2 in the table (which contains yes, no, n/a)
dropDownForChecklistAnswers.DataBind();
ERROR: dropDownForChecklistAnswers does not exist in the current context???
please advise
EDIT;
thanks for reply. I have
public void OnReptDataBound(object sender, RepeaterItemEventArgs e)
{
ClarkeDBDataContext db1 = new ClarkeDBDataContext();
List<string> CLRC =
(from choice in db1.Checklist_Record_Choices
select choice.Text).ToList();
DropDownList ddl = (DropDownList)e.Item.FindControl("dropDownForChecklistAnswers");
ddl.DataSource = CLRC;
}
but DropDownList ddl is coming back as object ref not set to instance of an object...why is it null??
You need to use FindControl to access a control which is part of a Repeater's template.
Subscribe to the OnItemDataBound of the Repeater (set the attribute OnItemDataBound="OnReptDataBound")
And then in your code behind do the following
void OnReptDataBound(object sender, RepeaterItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Item)
{
DropDownList ddl = (DropDownList )e.Item.FindControl("dropDownForChecklistAnswers");
ddl.DataSource = ....

CustomValidator handler not being called after user clicks the Update link on the GridView

On the DropDownList SelectedIndexChanged, the page posts back and records the name of the developer in the radiobutton. When the user clicks the Update link on the GridView, I want the customValidator to check if the Radiobutton is empty.
<EditItemTemplate>
<table>
<tr>
<td>
<asp:DropDownList ID="_ddlAllDev" runat="server" AutoPostBack = "true" DataTextField = "Text"
DataValueField = "Value" OnSelectedIndexChanged = "ddlAllDev_SelectedIndexChanged">
</asp:DropDownList>
</td>
</tr>
<tr>
<td>
<asp:RadioButtonList ID="_rblAllDev" runat="server" AutoPostBack = "true" DataTextField = "Text"
DataValueField = "Value" OnSelectedIndexChanged = "rblAllDev_SelectedIndexChanged">
</asp:RadioButtonList>
<asp:CustomValidator ID="_valDev" runat="server" ControlToValidate = "_rblAllDev" Text = "*"
ErrorMessage="Please choose at leat one developer for this task" OnServerValidate = "AllDev_ServerValidate" />
</td>
</tr>
</table>
</EditItemTemplate>
The problem is that it looks like the CustomerValidator handler is not even being called after the user click the UPPDATE link on the GridView. I have put a break point inside the method but the method is not even being called.
protected void AllDev_ServerValidate(object sender, ServerValidateEventArgs args)
{
}
Am I missing something?
Thanks for helping.

Finding in which row a Button was clicked in a GridView/Repeater

I am binding a Repeater. Each row (is that the right word?) in the Repeater has a Button and a HiddenField. How do I determine the Value of the HiddenField based on which Button was clicked?
Code behind for Button's OnClick event:
protected void btnButton1_Click(object sender, EventArgs e)
{
Button btnButton1 = (Button)sender;
// how do i get this row's HiddenField Value?
}
edit: the CommandArgument suggestion from Pleun works but I am still having issues. I need to find the row(?) in the Repeater that the Button belongs to as there is also a TextBox in each row and I would need its value. So ideally I want to get that row and go FindControl("TextBox1") etc etc. Sorry, should have stated that in my initial question
What I like to do is add a CommandArgument to the button. In this code its an imagebutton but the idea is the same. So also no need for an extra hidden field.
<asp:ImageButton ID="btnMail" ImageUrl="~/imgnew/prof/sendlink.png"
CommandArgument='<%# Eval("id")%>'
And in the _Click event do
string id = ((ImageButton)sender).CommandArgument;
Update:
If you need all the data, you need a different event. The data in the repeater is available as Item in
RepeaterCommandEventArgs
in the Command event (RepeaterCommandEventArgs)
for handling the Command event see this example
http://www.asp.net/data-access/tutorials/custom-buttons-in-the-datalist-and-repeater-cs
or
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.repeatercommandeventargs.aspx
If you using Repeater you can identify elements in each row in the ItemDataBound.
If you using gridview use RowDataBound
Hope this helps
You can traverse upwards by getting the button's Parent, then doing a FindControl() on that control.
Row parentRow = (Row)((Button)sender).Parent;
var tBox = (System.Web.UI.WebControls.TextBox)parentRow.FindControl("myTextBox")
You may have to play around to see how deep the button is nested and with what control types to get to the appropriate parent.
My markup code:
<asp:Repeater ID="RptFiles" runat="server">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>--</td>
<td><%#Eval("title")%></td>
<td>
<asp:FileUpload ID="fuVersion" runat="server" />
<asp:Button ID="btnUploadVersion" Text="Last opp" runat="server" OnClick="btnUploadVersion_Click" CommandArgument='<%#Eval("Id") %>' />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
My code behind
protected void Upload_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
var documentId = btn.CommandArgument;
//Get the Repeater Item reference
RepeaterItem item = btn.NamingContainer as RepeaterItem;
var fuVersion = (FileUpload)item.FindControl("fuVersion");
var filename = fuVersion.PostedFile.FileName
}

ListView fields not getting posted

I know I've done something like this before, but I have no idea why it isn't working now. I have a ListView with some textboxes. I want to read the text out of those boxes when I click a button (linkbutton, whatever).
<asp:ListView runat="server" ID="lv_bar" EnableViewState="true">
<LayoutTemplate>
<table>
<tr>
<th>Foo</th>
</tr>
<tr runat="server" id="itemPlaceholder"></tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><asp:LinkButton ID="lb_delete" CausesValidation="false" runat="server" Text="Del" /></td>
<td><asp:TextBox id="txt_foo" runat="server" /></td>
</tr>
</ItemTemplate>
</asp:ListView>
<asp:LinkButton ID="lb_add" CausesValidation="false" runat="server" Text="Add" />
And then here's the relevant code-behind stuff:
protected void Page_Load(object sender, EventArgs e)
{
lb_chapter_add.Click += lb_chapter_add_Click;
if (!IsPostBack)
{
lv_chapters.DataSource = new List<Foo>() { new Foo() { Name = "harbl"} };
lv_chapters.DataBind();
}
}
void lb_add_Click(object sender, EventArgs e)
{
foreach (ListViewDataItem item in lv_bar.Items)
{
var txt_foo = (TextBox)item.FindControl("txt_foo");
Response.Write("foo: " + txt_foo.Text);
}
Response.Write("<br />the end");
Response.End();
}
But what I see when I enter some text into txt_foo and click lb_add is just "the end". What am I doing wrong here?
The problem it that you are using a a non persistent object as DataSource.
Due to clicking the button, you generate a postback and lv_chapters does not contain any items. Set a breakpoint in the line where the foreach is and you will see that lv_chapters.Items in null, or that it's Count property returns 0.

Asp.Net ListView how to delete a row without deleting from datasource

Through CommandName="Delete" I try to delete a line from the ListView control but not from the datasource. On Pressing Delete I expect the webpage to reload and show me the updated ListView(with one line deleted). But nothing changes, the ListView will display the same content after pressing Delete. What do I do wrong?
<asp:ListView ID="ListView1"
DataSourceID="XmlDataSource1"
ItemContainerId="DataSection"
runat="server">
<LayoutTemplate>
<h3>Protocols to Upload...</h3>
<table border=0 style="background-color:#9C9EFF; width: 100%;">
<tr align=left>
<th>Region/Exam/Program</th><th>Protocol</th><th>Position</th>
</tr>
<asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><%#XPath("Location/Path")%></td>
<td><%#XPath("Location/Name")%></td>
<td><%#XPath("Location/Position")%></td>
<td style="width:40px">
<asp:LinkButton ID="SelectCategoryButton" runat="server" Text="Select" CommandName="Select"/>
</td>
</tr>
</ItemTemplate>
<SelectedItemTemplate>
<tr id="Tr1" runat="server" style="background-color:#F7F3FF">
<td><%#XPath("Location/Path")%></td>
<td><%#XPath("Location/Name")%></td>
<td><%#XPath("Location/Position")%></td>
<td style="width:40px">
<asp:LinkButton runat="server" ID="SelectCategoryButton" Text="Delete" CommandName="Delete" />
</td>
</tr>
</SelectedItemTemplate>
<%-- <ItemSeparatorTemplate>
<div style="height: 0px;border-top:dashed 1px #ff0000"></div>
</ItemSeparatorTemplate>--%>
</asp:ListView>
<asp:XmlDataSource ID="XmlDataSource1" XPath="HttpRequestBO/ProtocolsDTO/ProtocolDTO" runat="server"
DataFile="~/HttpRequestBo.Sample.xml"></asp:XmlDataSource>
And this is the code behind:
protected void Page_Load(object sender, EventArgs e)
{
}
protected void ListView1_OnItemDeleted(Object sender, ListViewDeletedEventArgs e)
{
if (e.Exception != null)
{
e.ExceptionHandled = true;
}
}
protected void ListView1_OnItemCommand(object sender, ListViewCommandEventArgs e)
{
if (String.Equals(e.CommandName, "Delete"))
{
ListViewDataItem dataItem = (ListViewDataItem)e.Item;
ListView1.Items.Remove(dataItem);
}
}
If I don't use the e.ExceptionHandled = true;, after pressing the Delete link the web page will come up with a "Specified method is not supported." message. Why?
If I use the above mentioned line, then the page refreshes but I can still see all original lines (although on debugging I can see that the ListVieItem collection now only contains an item less.)
It's because of the DatasourceID parameter, which binds at every single postback on the original file.
What you should do is to bind your list on the first page load only. The delete button will work as you expect then.
--- after comments.
OK.
In fact, the Delete command would work if you had defined the Delete method on your datasource. Since that's not what you want, you must define the ItemCommand event handler
and tell it to remove the ListViewItem that issued the event.
protected void yourListView_OnItemCommand(object sender, ListViewCommandEventArgs e)
{
if (String.Equals(e.CommandName, "Delete"))
{
ListViewDataItem dataItem = (ListViewDataItem)e.Item;
yourListView.Items.Remove(dataItem);
}
}
It will do so without touching the XML file beneath. Do not databind against it, else the "deleted" row will appear again.

Resources