I want to find "Label" control with ID = "Label" inside the "ListView" control. I was trying to do this with the following code:
((Label)this.ChatListView.FindControl("Label")).Text = "active";
But I am getting this exception: Object reference not set to an instance of an object .
What is wrong here ?
This is aspx code:
<asp:ListView ID="ChatListView" runat="server" DataSourceID="EntityDataSourceUserPosts">
<ItemTemplate>
<div class="post">
<div class="postHeader">
<h2><asp:Label ID="Label1" runat="server"
Text= '<%# Eval("Title") + " by " + this.GetUserFromPost((Guid?)Eval("AuthorUserID")) %>' ></asp:Label></h2>
<asp:Label ID="Label" runat="server" Text="" Visible="True"></asp:Label>
<div class="dateTimePost">
<%# Eval("PostDate")%>
</div>
</div>
<div class="postContent">
<%# Eval("PostComment") %>
</div>
</div>
</ItemTemplate>
</asp:ListView>
Listview is a databound control; so controls inside it will have different ids for different rows. You have to first detect the row, then grab the control. Best to grab such controls is inside an event like OnItemDataBound. There, you can do this to grab your control:
protected void myListView_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
var yourLabel = e.Item.FindControl("Label1") as Label;
// ...
}
}
If you want to grab it in Page_Load, you will have to know specific row and retrieve the control as:
var theLabel = this.ChatListView.Items[<row_index>].FindControl("Label1") as Label;
This function will get Author Name from a database, you just need to call your method to get Author Name and then return it
protected string GetUserFromPost(Guid? x)
{
// call your function to get Author Name
return "User Name";
}
And to bind label in the list view you have to do it in list view ItemDataBound Event
protected void ChatListView_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
Label lbl = e.Item.FindControl("Label") as Label;
lbl.Text = "Active";
}
}
Here are the list view aspx code changes (just add onitemdatabound="ChatListView_ItemDataBound"):
asp:ListView
ID="ChatListView"
runat="server"
DataSourceID="EntityDataSourceUserPosts"
onitemdatabound="ChatListView_ItemDataBound"
It should be Label1 in the arguement:
((Label)this.ChatListView.FindControl("Label1")).Text = "active";
This should be in a databound event.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listview.itemdatabound.aspx
Try it:
protected void ChatListView_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item is ListViewDataItem)
{
var yourLabel = e.Item.FindControl("Label1") as Label;
// ...
}
}
One simple solution to this problem, which avoids the FindControl code is to place OnInit on your label.
This would change your page code to this: <asp:Label ID="Label" runat="server" Text="" Visible="True" OnInit="Label_Init"></asp:Label>
And in your code behind you will now have a function like this:
protected void Label_Init(object sender, EventArgs e)
{
Label lblMyLabel = (Label)sender;
lblMyLabel.Text = "My Text";
}
Related
I have a Repeater with a certain DataSource (consisting of a list of images). The Repeater holds ImageButtons.
The aspx:
<asp:Panel ID="panSearch" runat="server" ScrollBars="Vertical" BorderColor="#333333" BorderStyle="Inset" Width="500" Height="200">
<asp:Repeater ID="Repeater" runat="server">
<ItemTemplate>
<asp:ImageButton OnClick="imgSearchResult_Click" BackColor="#333333" ID="imgSearchResult" height="32" width="32" runat="server" ImageUrl='<%# Eval("ImageUrl") %>'/>
</ItemTemplate>
</asp:Repeater>
</asp:Panel>
Additionally, I have a TextBox, which has a TextChanged-event in code-behind. I do a few things in there and at the end, my Repeater's DataSource will be overwritten with a new List of images (those images are put into the ImageButtons).
Repeater.DataSource = ImageList;
Repeater.DataBind();
My problem: Whenever my Repeater.DataSource is changed, it "clicks" the first ImageButton inside the Repeater. How do I prevent that from happening?
Full code:
My TextBox:
<asp:TextBox ID="textSearch" runat="server" Width="80" OnTextChanged="textSearch_TextChanged" ForeColor="Black" />
My TextChanged event:
protected void textSearch_TextChanged(object sender, EventArgs e)
{
string[] filesindirectory = Directory.GetFiles(Server.MapPath("~/Images/ORAS"));
List<System.Web.UI.WebControls.Image> ImageList = new List<System.Web.UI.WebControls.Image>(filesindirectory.Count());
foreach (string item in filesindirectory)
{
System.Web.UI.WebControls.Image myImage= new System.Web.UI.WebControls.Image();
myImage.ImageUrl = (String.Format("~/Images/ORAS/{0}", System.IO.Path.GetFileName(item)));
ImageList.Add(myImage);
}
Repeater.DataSource = ImageList;
Repeater.DataBind();
}
When I click on an ImageButton inside the Repeater (which is executed when the text in my TextBox is changed):
protected void imgSearchResult_Click(object sender, ImageClickEventArgs e)
{
var selectedImage = sender as ImageButton;
if (img1.ImageUrl == "~/Images/ORAS/Empty/000.png")
{
img1.ImageUrl = selectedImage.ImageUrl;
}
else if (img2.ImageUrl == "~/Images/ORAS/Empty/000.png")
{
img2.ImageUrl = selectedImage.ImageUrl;
}
else if (img3.ImageUrl == "~/Images/ORAS/Empty/000.png")
{
img3.ImageUrl = selectedImage.ImageUrl;
}
else if (img4.ImageUrl == "~/Images/ORAS/Empty/000.png")
{
img4.ImageUrl = selectedImage.ImageUrl;
}
else if (img5.ImageUrl == "~/Images/ORAS/Empty/000.png")
{
img5.ImageUrl = selectedImage.ImageUrl;
}
else if (img6.ImageUrl == "~/Images/ORAS/Empty/000.png")
{
img6.ImageUrl = selectedImage.ImageUrl;
}
else
{
ErrorMessage("Please remove one Image first!", true);
}
}
Pageload:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
img1.ImageUrl = "~/Images/ORAS/Empty/000.png";
img2.ImageUrl = "~/Images/ORAS/Empty/000.png";
img3.ImageUrl = "~/Images/ORAS/Empty/000.png";
img4.ImageUrl = "~/Images/ORAS/Empty/000.png";
img5.ImageUrl = "~/Images/ORAS/Empty/000.png";
img6.ImageUrl = "~/Images/ORAS/Empty/000.png";
LoadImages();
}
}
(LoadImages is almost 1:1 what's in my TextChanged function)
I really am not sure how (why) ASP.NET WebForms does it, but if you hit Enter and the form posts back, it will find the first control that implements IPostBackEventHandler and execute whatever event is bound to that. ImageButton implements it and so that's why it keeps firing the click event even though you didn't click on it. And, once again, only if you hit Enter.
I think that behaviour happens because the data posted back - __EVENTTARGET and __EVENTARGUMENT - are empty. Then ASP.NET goes bonkers.
You can solve it by putting a dummy button at the top of the page (or masterpage) and hide it using the style attribute. so:
<asp:Button ID="dummy" runat="server" style="display:none" />
Then in the init or load of your page (or masterpage) put
Form.DefaultButton = dummy.UniqueID;
That will force the button to capture the enter press instead of the arbitrary image button.
I have page with listview in it. There is label and dropdownlist in listview. I would like to access the text of label from ddlTags_Init() method.
Code:
<asp:ListView ID="ListView1" runat="server" DataSourceID="SqlDataSource1"
DataKeyNames="id_Image" onitemdatabound="ListView1_ItemDataBound">
<ItemTemplate>
<asp:Label ID="TagsLabel" runat="server" Text='<%# Eval("Tags") %>' />
<asp:DropDownList ID="ddlTags" runat="server" OnInit="ddlTags_Init" >
</asp:DropDownList>
</ItemTemplate>
</asp:ListView>
Code behind:
protected void ddlTags_Init(object sender, EventArgs e)
{
DropDownList ddlTags = (DropDownList)sender;
Label lblTag = (Label)ddlTags.Parent.FindControl("TagsLabel");
string text=lblTag.Text;
}
At the moment i am stuck with
Label lblTag = (Label)ddlTags.Parent.FindControl("TagsLabel");
Anyone knows what am i missing?
Thanks, Jim
Assuming that there are more than 1 elements in the listview datasource, why don't you put your code in the ItemDataBound handler? I think that it should work.
Init is too early to get the bind value of Label. In other words, label value hasn't been bind yet.
Instead you might want to consider using ItemDataBound method.
<asp:ListView ID="ListView1" runat="server"
OnItemDataBound="ListView1_ItemDataBound" ...>
....
</asp:ListView>
protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
var ddlTags = e.Item.FindControl("ddlTags") as DropDownList;
var tagsLabel = e.Item.FindControl("TagsLabel") as Label;
}
}
I have a ListView control with DataPager, i am trying to show results from database into ListView the database have field in which i have store content from ajaxhtmlextender i have bind ListView with database like this
protected void ListEvents()
{
conn = new SqlConnection(connSting);
cmdListEvent = new SqlCommand("SELECT * FROM LatestEvents",conn);
table = new DataTable();
conn.Open();
adpter = new SqlDataAdapter(cmdListEvent);
adpter.Fill(table);
ListEvent.DataSource = table;
ListEvent.DataBind();
conn.Close();
}
and the .aspx file
<asp:ListView ID="ListEvent" runat="server"
OnItemDataBound="ListEvent_ItemDataBound" >
<LayoutTemplate>
<asp:PlaceHolder runat="server" ID="itemPlaceholder"></asp:PlaceHolder>
</LayoutTemplate>
<ItemTemplate>
<div class="contmainhead">
<h1 id="evhead"><asp:Label ID="LabelTittle" runat="server"><%#Eval("Tittle") %></asp:Label></h1>
</div>
<div class="contmain">
<asp:Label ID="LabelBody" runat="server"> <%#Eval("Body") %></asp:Label>
</div>
</ItemTemplate>
</asp:ListView>
It is giving the intended results but the problem is the label
<asp:Label ID="LabelBody" runat="server"> <%#Eval("Body") %></asp:Label>
showing all the formatted text and images as html markup, i know to work the label perfectly i have to use this function
Server.HtmlDecode();
i tried it like this
protected void ListEvent_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
Label LabelBody = (Label)e.Item.FindControl("LabelBody");
LabelBody.Text = Server.HtmlDecode(LabelBody.Text);
}
}
But the label shows nothing. . so how can i make the label show the content correctly?
Your help will be greatly appreciated . .Thanx
protected void ListEvent_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
ListViewDataItem dataItem = (ListViewDataItem) e.Item;
Label LabelBody = (Label)e.Item.FindControl("LabelBody");
LabelBody.Text = (string) DataBinder.Eval(dataItem.DataItem, "Body");
}
}
Please make sure there is a column named in your returned datatable
and also remove the <%# EVAL %> tag from the text attribute of your label, leave it empty or do not specify the attribute in your aspx
try
<asp:Label ID="LabelBody" runat="server" text='<%#Eval("Body") %>' />
EDIT :
if the above didn't work try :
<asp:Label ID="LabelBody" runat="server" text="<% #Eval("Body").ToString() %>" />
It has been so long since I've used Web Forms I find myself not remembering most of the perks.
I have a user control that has a button, a repeater and the ItemTemplate property of the repeater is another user control.
<asp:Button runat="server" ID="btnAdd" CssClass="btn" Text="Add" OnClick="btnAdd_Click"/>
<br/>
<asp:Repeater runat="server" ID="rptrRequests">
<ItemTemplate>
<uc1:ucRequest ID="ucNewRequest" runat="server" />
</ItemTemplate>
</asp:Repeater>
The idea is that when the user clicks on the Add button a new instance of the ucRequest is added to the collection. The code behind is as follows:
public partial class ucRequests : UserControl
{
public List<ucRequest> requests
{
get
{
return (from RepeaterItem item in rptrRequests.Items
select (ucRequest) (item.Controls[1])
).ToList();
}
set
{
rptrRequests.DataSource = value;
rptrRequests.DataBind();
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack) return;
requests = new List<ucRequest>();
}
protected void btnAdd_Click(object sender, EventArgs e)
{
var reqs = requests;
reqs.Add(new ucRequest());
requests = reqs;
}
}
After much googling I now remember that I should be binding the Repeater in the OnInit method in order for the ViewState to put the captured data of the controls within the ucRequest control on them between post backs but when I try to do that I will always have a single instance of the control on the Repeater since its Items collection is always empty.
How could I manage to do this?
Thanks in advance.
You just need control ids in view state stead of entire control collection.
<%# Control Language="C#" AutoEventWireup="true"
CodeBehind="ucRequests.ascx.cs"
Inherits="RepeaterWebApplication.ucRequests" %>
<asp:Button runat="server" ID="btnAdd" CssClass="btn" Text="Add"
OnClick="btnAdd_Click" />
<br /><asp:PlaceHolder runat="server" ID="PlaceHolder1"></asp:PlaceHolder>
<%# Control Language="C#" AutoEventWireup="true"
CodeBehind="ucRequest.ascx.cs"
Inherits="RepeaterWebApplication.ucRequest" %>
<asp:TextBox runat="server" ID="TextBox1"></asp:TextBox>
private List<int> _controlIds;
private List<int> ControlIds
{
get
{
if (_controlIds == null)
{
if (ViewState["ControlIds"] != null)
_controlIds = (List<int>) ViewState["ControlIds"];
else
_controlIds = new List<int>();
}
return _controlIds;
}
set { ViewState["ControlIds"] = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
foreach (int id in ControlIds)
{
Control ctrl = Page.LoadControl("ucRequest.ascx");
ctrl.ID = id.ToString();
PlaceHolder1.Controls.Add(ctrl);
}
}
}
protected void btnAdd_Click(object sender, EventArgs e)
{
var reqs = ControlIds;
int id = ControlIds.Count + 1;
reqs.Add(id);
ControlIds = reqs;
Control ctrl = Page.LoadControl("ucRequest.ascx");
ctrl.ID = id.ToString();
PlaceHolder1.Controls.Add(ctrl);
}
Try to get the ucRequests during the OnItemDatabound event, at that point you can edit the content of itemtemplate of the repeater. You can get there after the postback caused by the click on the add button. Here's a sample with a similar scenario
I put a hyperlink inside a datalist..
<ItemTemplate>
<asp:HyperLink ID="HyperLink1" runat="server">'<%# Eval("ThreadTitle") %>'</asp:HyperLink>
<br />
<br />
</ItemTemplate>
I want it to enable it to be pressed so that the datalist event will be triggered and transfer me to another page:
protected void DataList1_SelectedIndexChanged(object sender, EventArgs e)
{
Server.Transfer("AnswerQuestion.aspx?x=" + DataList1.DataKeyField + "&question=" + DataList1.SelectedValue + "&time=" + DateTime.Now);
}
Unfortunately, the link seems to be disabled and I cant press on it to trigger the DataList Selected event..
How can I make the hyperlink active ?
If you want to trigger a selecteditemchaned event use a LinkButton instead of hyperlink.
<asp:DataList ID="DataList1" runat="server"
onselectedindexchanged="DataList1_SelectedIndexChanged">
<ItemTemplate>
<asp:LinkButton ID="sjdj" runat="server" CommandName="Select">
<%# Container.DataItem %></asp:LinkButton>
</ItemTemplate>
</asp:DataList>
In the code behind have
protected void DataList1_SelectedIndexChanged(object sender, EventArgs e)
{
Server.Transfer("~/jjtestjj.aspx?" + DataList1.DataKeyField);
}
why arent you using the Hyperlink as a hyperlink?
You can set the NavigationURL and Text using the OnItemDataBound (or equivalent) event.
this code works with an asp:Repeater:
protected void Row_DataItem(object row, RepeaterItemEventArgs args)
{
if (args.Item.ItemType == ListItemType.AlternatingItem || args.Item.ItemType == ListItemType.Item)
{
var item = (DataItemPOCO)args.Item.DataItem;
var link = (HyperLink)args.Item.FindControl("HyperLink1");
link.Text = item.LinkText;
link.NavigateUrl = item.URL;
}
}