Acessing a datacontrol from a listview in asp.net c - c#

I''ve been working at this for a good while now. I'm simply trying to access something that is in a datalist. I can get items just fine from the PageLoad, even set some dynamic items.. but I can't acess controls from my button click handler.
I've tried other variations such as
ListView1.FindControl("DropDownList1") as DropDownList;
Which gives a NULL.
I've tried
<asp:LinkButton id="addPro" runat="server" CommandArgument='<%# DropDownList1.SelectedItem.Text %>' onCommand ="addPro_Click">Add To Cart</asp:LinkButton>
Which says it can't find the data control in scope.
<asp:ListView ID="ListView1" runat="server"
DataKeyNames="Expr7,Expr1,productNo" DataSourceID="SqlDataSource1">
<AlternatingItemTemplate>
<span style="">
<asp:Label ID="productNameLabel" runat="server"
Text='<%# Eval("productName") %>' />
<br />
<asp:Image runat="server" height = "300" ImageUrl='<%# Eval("img") %>'></asp:Image>
<br />
Description:<br />
<asp:Label ID="itemNotesLabel" runat="server" Text='<%# Eval("itemNotes") %>' />
<br />
stock:
<asp:Label ID="stockLabel" runat="server" Text='<%# Eval("stock") %>' />
<br />
price:
<asp:Label ID="priceLabel" runat="server" Text='<%# "$"+ Eval("price")+".00" %>' />
<br />
Quantitiy: <asp:DropDownList id="DropDownList1" runat="server"> </asp:DropDownList>
<br />
<asp:LinkButton id="addPro" runat="server" CommandArgument='<%# Eval("productNo") %>' onCommand ="addPro_Click">Add To Cart</asp:LinkButton>
<br /><br /><br />
<br /></span>
</AlternatingItemTemplate>
On click
protected void addPro_Click(Object sender, CommandEventArgs e)
{
string addr = "";
string v = Request.QueryString["cat"];
if (v != null)
{
v = "cat=" + v+"&";
}
else
{
v = "";
}
DropDownList stockDD = (DropDownList) FindControl("DropDownList1");
if (stockDD != null)
addr = "~/product.aspx/?" + v + "add=" + e.CommandArgument.ToString() + "&quant=" + stockDD.SelectedItem.Text;
else
addr = "ERROR!";
Response.Redirect(addr+e.CommandArgument.ToString());
ListView1.ItemDataBound += (sa, ea) =>
{
DropDownList stockD = ea.Item.FindControl("DropDownList1") as DropDownList;
Label l = ea.Item.FindControl("Lable12") as Label;
l.Text = stockD.SelectedItem.Text;
addr = "~/product.aspx/?" + v + "add=" + e.CommandArgument.ToString() + "&quant=" + stockD.SelectedItem;
};
// Response.Redirect(addr);
}
Any help in the right direction will help a ton! Thanks!

Try this:
LinkButton lbSender = (LinkButton)sender;
ListViewDataItem lvItem = (ListViewDataItem)(lbSender.Parent);
DropDownList DropDownList1 = lvItem.FindControl("DropDownList1");
ListView.Items is a collection of ListViewDataItem which inherits ListViewItem, which inherits from Control. This means you can find any control in its Controls collection using FindControl. You just have to look at the heirarchy.
Docs for ListView: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listview.aspx
Docs for ListViewDataItem: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listviewdataitem.aspx
Docs for ListViewItem: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listviewitem.aspx
Docs for Control: http://msdn.microsoft.com/en-us/library/system.web.ui.control.aspx

Related

setting CSS class to selected ASP.NET Listview Item

I have a listview which I want highlight the items on click.
Using the below code, I could set the CSS class. But the foreach loop doesn't clear the css class set before.
<asp:ListView ID="ListView2" runat="server" SelectedIndex="0" onitemcommand="ListView2_ItemCommand">
<ItemTemplate>
<asp:Panel ID="Panel8" runat="server" CssClass="left-listitem-div">
<asp:Image ID="Image1" runat="server" AlternateText="User Icon" ImageUrl='<%# Eval("UserType").ToString() == "AD_USER" ? "Images/icons/ldapuser32px.png" : "Images/icons/user32px.png" %>' CssClass="list-group-icon" />
<asp:Label ID="ListUserID" runat="server" Text ='<%#Eval("UserID") %>' CssClass="list-group-id" style="display:none;" />
<asp:LinkButton ID="ListFullName" runat="server" Text='<%#Eval("FullName") %>' CssClass="list-group-name" CommandName="select" CommandArgument = '<%# Eval("UserID") %>' Font-Underline="False" ForeColor="Black" Width="130" Height="30" />
<asp:Label ID="ListUserName" runat="server" Text='<%#Eval("UserName") %>' CssClass="list-group-username" style="display:none;" />
<asp:Label ID="ListUserType" runat="server" Text='<%#Eval("UserType") %>' CssClass="list-group-usertype" style="display:none;" />
<asp:Label ID="ListUserEnabled" runat="server" Text='<%#Eval("Enabled") %>' CssClass="list-group-enabled" style="display:none;" />
<asp:Label ID="ListUserDescription" runat="server" Text ='<%#Eval("Description") %>' CssClass="list-group-descri" style="display:none;" />
</asp:Panel>
</ItemTemplate>
</asp:ListView>
The Codebehind is below.
I used SelectedItemTemplate, but Listview selectedIndex is not changing.
If I set the selectedIndex on ItemCommand event, Its affecting only at the next postback.
protected void ListView2_ItemCommand(object sender, ListViewCommandEventArgs e)
{
if (e.Item.FindControl("Panel8") != null && e.Item.FindControl("Panel8") is Panel)
{
foreach (ListViewItem li in ListView2.Items)
{
Panel lipp = (Panel)e.Item.FindControl("Panel8");
lipp.CssClass = "left-listitem-div";
}
Panel pp = (Panel)e.Item.FindControl("Panel8");
pp.CssClass = "left-listitem-div selected";
}
}
Ok, don't change the event, because you use commandEventargs.
Just set the SelectIndex of the listview and then change the css for that item.
protected void ListView2_ItemCommand(object sender, ListViewCommandEventArgs e)
{
(sender as ListView).SelectedIndex = e.Item.DataItemIndex;
(e.Item.FindControl("Panel8") as Panel).CssClass += "SelectedCss";
}
In the loop you alwas refer to the currently selected item, that's your problem.
Change the loop to this: --> li
foreach (ListViewItem li in ListView2.Items)
{
Panel lipp = (Panel)li.FindControl("Panel8");
lipp.CssClass = "left-listitem-div";
}

Make repeater row checkable

I have a ASP.NET repeater consists of image and label(wrap inside a div).
I want to make the repeater row work like a checkbox.
<asp:Repeater ID="rpt" runat="server">
<ItemTemplate>
<div class="divItem">
<asp:HiddenField ID="hfIID" runat="server" Value='<%# Eval("ID") %>' />
<asp:Image ID="imgItem" runat="server" ImageUrl='<%# Eval("ImageURL") %>' />
<asp:Label ID="lblName" runat="server" Text='<%# Eval("ItemName") %>'></asp:Label>
</div>
</ItemTemplate>
</asp:Repeater>
For example, the repeater have 10 items.
When a user select item 3 and item 5(similar like a checkbox) and press Save, I need to get the selected Item ID.
you will need to add some client side scripting with jquery.
Here's how to do it:
in your .aspx define repeater as :
<asp:Repeater ID="rpt" runat="server">
<ItemTemplate>
<div class="divItem" id='divItem<%# Eval("ID") %>'>
<asp:HiddenField ID="hfSelected" runat="server" />
<asp:HiddenField ID="hfIID" runat="server" Value='<%# Eval("ID") %>' />
<asp:Image ID="imgItem" runat="server" ImageUrl='<%# Eval("ImageURL") %>' />
<asp:Label ID="lblName" runat="server" Text='<%# Eval("ItemName") %>'></asp:Label>
</div>
</ItemTemplate>
</asp:Repeater>
and then add this javascript:
<script>
$(function () {
$('.divItem').click(function () {
var item = $(this);
item.toggleClass("divItemSelected"); //mark div as selected: set background color, etc...
var selector = "#" + item.attr("id") + " input[type='hidden'][id*='hfSelected']";
var selected = $(selector).val();
if (selected == "true") {
$(selector).val("false");
} else {
$(selector).val("true");
}
});
});
</script>
And then in code-behind on button click, you do this:
protected void OnSaveClick(object sender, EventArgs e)
{
foreach (RepeaterItem item in rpt.Items)
{
HiddenField hfSelected = item.FindControl("hfSelected") as HiddenField;
bool selected = false;
bool.TryParse(hfSelected.Value, out selected);
if (selected)
{
HiddenField hfIID = e.Item.FindControl("hfIID") as HiddenField;
int id = Convert.ToInt32(hfIID.Value);
// do appropriate action as needed.
}
}
}
Hope this helps!
Regards,
Uros

How to bind repeater ItemDataBound, to update on dropdownlist SelectedIndexChanged

Im a rookie on ASP.Net and been stuck for this for a while.
Everytime the index of my dropdown changes i want to fill my repeater with objects.
This works fine, but when im selecting a value in my dropdown that dosent contain any objects the old objects from the last call is still there, i want them to disappear.
I've tried to clear the items from the repeater using Datasource=null and then do a Databind again, but that dosent work.
I think it has with the ItemDataBound event on my repeater.
The ItemDatabound is not called when i select a value in the dropsdownlist that dosent contain any objects.
ItemDataBound CODE:
protected void rptStudentQuestion_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Label lblAnswer = e.Item.FindControl("lblAnswer") as Label;
TextBox tbxAnswer = e.Item.FindControl("tbxAnswer") as TextBox;
Button btnSend = e.Item.FindControl("btnSend") as Button;
if (lblAnswer.Text == "" || lblAnswer == null)
{
lblAnswer.Visible = false;
lblAnswer.Enabled = false;
tbxAnswer.Visible = true;
tbxAnswer.Enabled = true;
btnSend.Enabled = true;
btnSend.Visible = true;
}
else
{
lblAnswer.Visible = true;
lblAnswer.Enabled = true;
tbxAnswer.Visible = false;
tbxAnswer.Enabled = false;
btnSend.Enabled = false;
btnSend.Visible = false;
}
}
}
OnSelectedIndexChanged CODE:
protected void DrpdwnLectureName_SelectedIndexChanged(object sender, EventArgs e)
{
string SelectedLecture = DrpdwnLectureName.SelectedValue;
string user = Server.HtmlEncode(Context.User.Identity.Name).ToString();
using (var client = new WCFReference.SRSServiceClient())
{
var LectureList = client.GetTeacherLecture(user);
foreach (var item in LectureList)
{
if (item.LectureName == DrpdwnLectureName.SelectedValue)
{
var list = client.GetStudentQuestions(item.LectureID, user);
rptStudentQuestion.DataSource = list;
rptStudentQuestion.DataBind();
}
}
}
}
Markup CODE:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:DropDownList ID="DrpdwnLectureName" AutoPostBack="True" runat="server" OnSelectedIndexChanged="DrpdwnLectureName_SelectedIndexChanged"></asp:DropDownList>
<asp:Panel ID="PrintPanel" runat="server">
<asp:Label ID="Label1" runat="server" Text="Gör en .pdf på besvarade frågor"></asp:Label>
<asp:Button ID="btnDoPdf" runat="server" Text="Button" OnClick="btnDoPdf_Click" />
</asp:Panel>
<asp:Repeater ID="rptStudentQuestion" runat="server" OnItemCommand="rptStudentQuestion_ItemCommand" OnItemDataBound="rptStudentQuestion_ItemDataBound">
<ItemTemplate>
<asp:Label ID="lblQuestion" runat="server" Text='<%# Eval("StudentQuestionQuestion") %>'></asp:Label>
<br />
<asp:TextBox ID="tbxAnswer" runat="server" Visible="false"></asp:TextBox>
<asp:Button ID="btnSend" CommandName="SendAnswer" runat="server" Text="Skicka svar" CommandArgument='<%# Eval("StudentQuestionID") %>' />
<br />
<asp:Label ID="lblAnswer" runat="server" Text='<%# Eval("StudentQuestionAnswer") %>' Visible="false"></asp:Label>
<br />
</ItemTemplate>
</asp:Repeater>
</ContentTemplate>
</asp:UpdatePanel>
Updated Code as Requested(Snippet from DrpdwnLectureName_SelectedIndexChanged)
if (item.LectureName == DrpdwnLectureName.SelectedValue)
{
var list = client.GetStudentQuestions(item.LectureID, user);
if (list.Count() > 0)
{
rptStudentQuestion.Visible = true;
rptStudentQuestion.DataSource = list;
rptStudentQuestion.DataBind();
}
else
{
rptStudentQuestion.Visible = false; // In debug it preforms this, but nothing happens.
}
}
This is not a solution, but can solve your update panel updating problem. You can control updatepanel update manually doing this:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="false">
<ContentTemplate>
<asp:DropDownList ID="DrpdwnLectureName" AutoPostBack="True" runat="server" OnSelectedIndexChanged="DrpdwnLectureName_SelectedIndexChanged"></asp:DropDownList>
<asp:Panel ID="PrintPanel" runat="server">
<asp:Label ID="Label1" runat="server" Text="Gör en .pdf på besvarade frågor"></asp:Label>
<asp:Button ID="btnDoPdf" runat="server" Text="Button" OnClick="btnDoPdf_Click" />
</asp:Panel>
<asp:Repeater ID="rptStudentQuestion" runat="server" OnItemCommand="rptStudentQuestion_ItemCommand" OnItemDataBound="rptStudentQuestion_ItemDataBound">
<ItemTemplate>
<asp:Label ID="lblQuestion" runat="server" Text='<%# Eval("StudentQuestionQuestion") %>'></asp:Label>
<br />
<asp:TextBox ID="tbxAnswer" runat="server" Visible="false"></asp:TextBox>
<asp:Button ID="btnSend" CommandName="SendAnswer" runat="server" Text="Skicka svar" CommandArgument='<%# Eval("StudentQuestionID") %>' />
<br />
<asp:Label ID="lblAnswer" runat="server" Text='<%# Eval("StudentQuestionAnswer") %>' Visible="false"></asp:Label>
<br />
</ItemTemplate>
</asp:Repeater>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="DrpdwnLectureName" />
</Triggers>
</asp:UpdatePanel>
and when you want to update the panel in code, you call: "UpdatePanel1.Update()"
if (item.LectureName == DrpdwnLectureName.SelectedValue)
{
var list = client.GetStudentQuestions(item.LectureID, user);
if (list.Count() > 0)
{
rptStudentQuestion.Visible = true;
rptStudentQuestion.DataSource = list;
rptStudentQuestion.DataBind();
}
else
{
rptStudentQuestion.Visible = false; // In debug it preforms this, but nothing happens.
UpdatePanel1.Update() //This 'force' updatepanel updating
}
}

Data lost in the postback

I need a way for a piece of data to presist across postbacks. Is there a way besides, cookies, and sessions?
I've got a listbox, when clicked, the selected index changed event takes a session which contains user id and feeds it to a method that fetches user's name, etc. Then I use FindControl method to locate a button inside the form view. I set the button's text property with data just fetched such as first and last name.
It works on the initial load, but if I click on other records in the listbox second time the text property is not set.
I did not write this code - I'm trying to make chages.
Here is the list box:
<asp:ListBox ID="lbxUpcommingEvents" runat="server" DataSourceID="odsUpcommingEvents"
Rows="6" DataTextField="Title" DataValueField="id" AutoPostBack="true"
Width="206px" OnSelectedIndexChanged="lbxUpcommingEvents_OnSelectedIndexChanged" />
Listbox'x on selected index changed:
protected void lbxUpcommingEvents_OnSelectedIndexChanged(object sender, EventArgs e)
{
pnlEventsSignUp.Visible = true;
string _selectedItemValue = lbxUpcommingEvents.SelectedValue.ToString();
LoadName();
}
protected void LoadName()
{
MembershipUser user = Membership.GetUser();
DataSetTableAdapters.MemberInfoTableAdapter da = new DataSetTableAdapters.MemberInfoTableAdapter();
Guid _memberId = Guid.Empty;
_memberId = new Guid(Session["myId"].ToString());
DataSet.MemberInfoDataTable dt = da.GetMember(_memberId);
if (dt.Rows.Count == 1)
{
DataSet.MemberInfoRow mr = dt[0];
RolloverLink rlnkSignUp = (RolloverLink)(fvEventSignUp.FindControl("rlnkSignUp"));
rlnkSignUp.Text = "I, " + mr.firstname + " " + mr.lastname + " will be attending this event.";
}
}
Here is markup for the form view where I set the RolloverLinkButton's text property.
<asp:Panel runat="server" ID="pnlEventsSignUp" visible="false">
<div class="dashedline" ></div>
<asp:FormView ID="fvEventSignUp" runat="server" DataSourceID="SqlDataSource1"
DataKeyNames="id" Width="100%" >
<ItemTemplate>
<h2>
<asp:Label Text='<%# Eval("title") %>' runat="server" ID="titleLabel" />
</h2>
<div class="itemdetails">
<br />
location:
<h3>
<asp:Label ID="locationLabel" runat="server" Text='<%# ShowLocationLink(Eval("locationname"),Eval("location")) %>' />
</h3>
<p>
<asp:Label Text='<%# Eval("starttime","{0:D}") %>' runat="server" ID="itemdateLabel" CssClass="GeneralText" />
<asp:Label Text='<%# ShowDuration(Eval("starttime"),Eval("endtime")) %>' runat="server" ID="Label1" CssClass="GeneralText" />
</p>
</div>
<div class="downloadevent">
<a href="#">
<img src="images/icon_download_event.gif" alt="Download this event to your personal calendar"
width="15" height="26" /></a><a href='<%# "events_download.ashx?EventID=" + Convert.ToString(Eval("id")) %>'>Add
this event to your personal calendar</a>
</div>
<Club:ImageThumbnail ID="thumb1" runat="server" ImageSize="Large" PhotoID='<%# Eval("photo") %>' />
<p>
<asp:Label Text='<%# Eval("description") %>' runat="server" ID="descriptionLabel" />
</p>
<div class="dashedline" ></div>
<asp:Panel ID="panel1" runat="server" CssClass="actionbuttons" Visible='<%#User.IsInRole("Administrators") %>'>
<table border="0" cellpadding="2" cellspacing="2">
<tr>
<td>
<asp:Label runat="server" ID="Label2" Text="Action<br />Required" Width="80px" />
</td>
<td>
<img src="images/RedArrow.jpg" alt="Red Arrow Right" />
</td>
<td>
<asp:CheckBox runat="server" ID="cbxCert" Height="30px" Text="Check to Confirm Attendance" /><br />
<asp:CustomValidator runat="server" ID="rfvConfirm"
ErrorMessage="You must check the box to continue" Font-Bold="true"
ForeColor="#cc0000" ClientValidationFunction="ensureChecked" /> <br />
<Club:RolloverLink ID="rlnkSignUp" runat="server"
/>
</td>
</tr>
</table>
</asp:Panel>
</ItemTemplate>
</asp:FormView>
</asp:Panel>
You can use ViewState. Since you are dynamically looking up the button, setting a property is quicker and we can then let Asp.Net find the button and set its text via one of the two methods I explain below:
public string rlnkSignUpText
{
get { return Convert.ToString(ViewState["rlnkSignUpText"] ?? "default value"); }
set { ViewState["rlnkSignUpText"] = value; }
}
Replace your code that searches for the button and assigns the text with:
rlnkSignUpText = "I, " + mr.firstname + " " + mr.lastname + " will be attending this event.";
Then use one of these methods to set the text to the control:
1) Use the control's OnPreRender event:
To render it, add OnPreRender="rlnkSignUp_PreRender" to your xaml like this:
<Club:RolloverLink ID="rlnkSignUp" runat="server" OnPreRender="rlnkSignUp_PreRender" />
Then in your codebehind:
protected void rlnkSignUp_PreRender(object sender, EventArgs e)
{
RolloverLink rlnkSignUp = (RolloverLink)sender;
rlnkSignUp.Text = rlnkSignUpText;
}
2) Bind the property and control together:
Instead of using the control's PreRender you can bind to the property with:
<Club:RolloverLink ID="rlnkSignUp" runat="server" Text='<%# rlnkSignUpText %>' />
You then need to call DataBind in your Page_PreRender() like so:
void Page_PreRender(object sender, EventArgs e)
{
DataBind();
}
Have you enabled ViewState in the control.
Enable View State

listview and datalist not updating,inserting

Data entered in textboxes is not getting updated in database. In debug mode I see that text1 and text2 in ItemUpdating event contain the same values as they had before calling ItemUpdating.
Here's my listview control:
<asp:ListView ID="ListView1" runat="server"
onitemediting="ListView1_ItemEditing"
onitemupdating="ListView1_ItemUpdating"
oniteminserting="ListView1_ItemInserting">
//LayoutTemplate removed
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%#Eval("id")%>'></asp:Label>
<asp:Label ID="Label3" runat="server" Text='<%#Eval("text1")%>'></asp:Label>
<asp:LinkButton ID="LinkButton2" CommandName="Edit" runat="server">Edit</asp:LinkButton>
<asp:LinkButton ID="LinkButton4" CommandName="Delete" runat="server">Delete</asp:LinkButton>
</ItemTemplate>
<EditItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%#Eval("id")%>'></asp:Label>
<asp:TextBox ID="TextBox1" runat="server" Text='<%#Eval("text1")%>' TextMode="MultiLine" />
<asp:TextBox ID="TextBox2" runat="server" Text='<%#Eval("text2")%>' Height="100" TextMode="MultiLine" />
<asp:LinkButton ID="LinkButton1" CommandName="Update" CommandArgument='<%# Eval("id")%>' runat="server">Update</asp:LinkButton>
<asp:LinkButton ID="LinkButton5" CommandName="Cancel" runat="server">Cancel</asp:LinkButton>
</EditItemTemplate>
<InsertItemTemplate>
<asp:TextBox ID="TextBox3" runat="server" TextMode="MultiLine" Height="100"></asp:TextBox>
<asp:TextBox ID="TextBox4" runat="server" Height="100" TextMode="MultiLine"></asp:TextBox>
<asp:LinkButton ID="LinkButton3" runat="server">Insert</asp:LinkButton>
</InsertItemTemplate>
</asp:ListView>
Codebehind file:
protected void ListView1_ItemEditing(object sender, ListViewEditEventArgs e)
{
ListView1.EditIndex = e.NewEditIndex;
BindList();
}
protected void ListView1_ItemUpdating(object sender, ListViewUpdateEventArgs e)
{
ListViewItem myItem = ListView1.Items[ListView1.EditIndex];
Label id = (Label)myItem.FindControl("Label1");
int dbid = int.Parse(id.Text);
TextBox text1 = (TextBox)myItem.FindControl("Textbox1");
TextBox text2 = (TextBox)myItem.FindControl("Textbox2");
//tried to work withNewValues below, but they don't work, "null reference" error is being thrown
//text1.Text = e.NewValues["text1"].ToString();
//text2.Text = e.NewValues["text2"].ToString();
//odbc connection routine removed.
//i know that there should be odbc parameteres:
comm = new OdbcCommand("UPDATE table SET text1 = '" + text1.Text + "', text2 = '" + text2.Text + "' WHERE id = '" + dbid + "'", connection);
comm.ExecuteNonQuery();
conn.Close();
ListView1.EditIndex = -1;
//here I databind ListView1
}
What's wrong with updating of text1.Text, text2.Text in ItemUpdating event? Should I use e.NewValues property? If so, how to use it?
Thanks in advance for any help.
Pffff. 2 days wasted. Just found out that I forgot to use to use in Page_Load():
if (!IsPostBack)
{
ListView1.DataSource = ds;
ListView1.DataBind();
}

Categories

Resources