Findcontrol in Listview returns null - asp.net

I'm trying to Change Text property of hyperlinks inside a listview but Findcontrol returns null although I know it should returns a hyperlink.
Listview:
<asp:ListView ID="ListView2" OnDataBound="ListView2_DataBound" runat="server">
<ItemTemplate>
<asp:HyperLink ID="HyperLinkMenuItem" runat="server" class="btn btn-default" Text='<%#Eval("CatName") %>' NavigateUrl='<%# "City.aspx?City="+ Request.QueryString["City"]+"&CatID="+Eval("CatID") %>'></asp:HyperLink>
</ItemTemplate>
</asp:ListView>
Behind Code:
protected void ListView2_DataBound(object sender, EventArgs e)
{
foreach (ListViewDataItem item in ListView1.Items)
{
HyperLink MenuItem = (HyperLink) item.FindControl("HyperLinkMenuItem");
if (MenuItem.Text == "Something")
{
MenuItem.Text = "";
}
}
}

You need use ItemDataBound event with ListViewItemEventArgs.
<asp:ListView ID="ListView2"
OnItemDataBound="ListView2_ItemDataBound" runat="server">
In addition, you do not need to loop through ListView1 (I have no clue where ListView1 came from)
protected void ListView2_DataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
var menuItem = e.Item.FindControl("HyperLinkMenuItem") as HyperLink;
}
}

Related

How to retrieve a button inside a ListView which is inside a Repeater

I want to access the button btn3 inside a ListView. The ListView itself is in the ItemTemplate of a Repeater.
<asp:Repeater runat="server" ID="rep1">
<ItemTemplate>
<asp:ListView ID="ListView1" runat="server" DataSourceID="SqlDataSource1">
...
<asp:Button ID="btn3" runat="server" Text='<%#Eval("likes").ToString()%>'/>
...
</asp:ListView>
</ItemTemplate>
</asp:Repeater>
When I try to access btn3 in the ItemDataBound event of the Repeater, the returned value is null:
protected void repeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Button btn1 = (Button)e.Item.FindControl("Btn3"); // btn1 is null
}
}
You can set the ItemDataBound event handler of the ListView:
<asp:Repeater runat="server" ID="rep1">
<ItemTemplate>
<asp:ListView ID="ListView1" runat="server" OnItemDataBound="ListView1_ItemDataBound" DataSourceID="SqlDataSource1">
...
</asp:ListView>
</ItemTemplate>
</asp:Repeater>
And retrieve the button in code-behind:
protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
Button btn3 = e.Item.FindControl("btn3") as Button;
...
}
}
If you want to do it in the Repeater ItemDataBound event handler (but I am not sure if the ListView is populated at that point):
protected void repeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
ListView ListView1 = e.Item.FindControl("ListView1") as ListView;
List<Button> buttons = new List<Button>();
foreach (ListViewItem lvItem in ListView1.Items)
{
buttons.Add(lvItem.FindControl("Btn3") as Button);
}
// Use the list of buttons
...
}
}

DropDownList's SelectedIndexChanged event calls all events

i'm using Asp .Net Web Forms. i have 2 dropDown list and 1 input field. I want when i change the item on the dropDown list or the field value to call some event but it calls all the events.
for example if i change size it calls Size_SelectedIndexChanged, then Color_SelectedIndexChanged, and then txtKolicina_TextChanged
if i change color it calls Color_SelectedIndexChanged, than Size_SelectedIndexChanged and then txtKolicina_TextChanged.
Any help?
<asp:DropDownList ID="Colors" runat="server" AutoPostBack="true" CssClass="form-control detal-page-input" Style="height: 30px;" OnSelectedIndexChanged="Colors_SelectedIndexChanged" AppendDataBoundItems="True" DataSourceID="LinqDataSource3" DataTextField="color" DataValueField="color" >
<asp:ListItem Text="" Value=""></asp:ListItem>
</asp:DropDownList>
<asp:DropDownList ID="Size" runat="server" OnSelectedIndexChanged="Size_SelectedIndexChanged" AppendDataBoundItems="true" AutoPostBack="true" CssClass="form-control detal-page-input" Style="height: 30px;" DataSourceID="LinqDataSource2" DataTextField="size" DataValueField="size" EnableViewState="true">
<asp:ListItem Text="" Value=""></asp:ListItem>
</asp:DropDownList>
<asp:TextBox Name="txtKolicina" ID="txtKolicina" runat="server" CssClass="form-control form-numberone detal-page-input" OnTextChanged="txtKolicina_TextChanged" ></asp:TextBox>
this is backEnd
protected void Size_SelectedIndexChanged(object sender, EventArgs e)
{
//do something
}
protected void Colors_SelectedIndexChanged(object sender, EventArgs e)
{
//do something
}
protected void txtKolicina_TextChanged(object sender, EventArgs e)
{
//do something
}
UPDATE
public string[] GetColor()
{
CMS_Shop_ModuleDataContext db = new CMS_Shop_ModuleDataContext();
var color = (from p in db.CMS_Articles
where
p.articleID == int.Parse(HiddenFieldArticalId.Value) ||
p.sameAsArticleID == int.Parse(HiddenFieldArticalId.Value)
//where p.articleID == 10049 || p.sameAsArticleID == 10049
select p.color).Distinct();
return color.ToArray();
}
public int GetColorCount()
{
CMS_Shop_ModuleDataContext db = new CMS_Shop_ModuleDataContext();
var color = (from p in db.CMS_Articles
where (p.articleID == int.Parse(HiddenFieldArticalId.Value)
|| p.sameAsArticleID == int.Parse(HiddenFieldArticalId.Value))
&& p.color != ""
select p.color);
return color.Distinct().Count();
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (GetColorCount() == 0)
{
Colors.Visible = false;
lblBoja.Visible = false;
}
else
{
Colors.Visible = true;
lblBoja.Visible = true;
}
Looks like you use View State and repopulate your DropDownLists in code behind on Postback. Can you show OnInit and OnLoad ?
Or just try this code:
if (!IsPostBack) {
// populate all drop downs lists
}
Ok i found what was the problem.
a change
EnableViewState="false"
to
EnableViewState="true"

asp net repeater checkbox

I use a Checkbox in a Repeater, how can I know which
Checkbox have changed in OnCheckedChanged?
I have tried to set id then checkbox is binding data, but
it will not work. Hope someone can help me
Thanks
/Mats
Check the sender(Event Target) parameter
protected void Chb_Changed(object sender, EventArgs e)
{
if (sender != null)
{
CheckBox cb=(CheckBox)sender;
string clickedCheckBoxID=cb.ID;
}
}
Try following . Please note that we can also bind some primary column let's say "ID" column in some hidden field then get in code behind.
ASPX Side
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="sqldtasource" >
<ItemTemplate>
<asp:CheckBox ID="chk" runat="server" AutoPostBack="true" Text='<%#Bind("Name")%>' OnCheckedChanged="Chb_Changed"/>
<asp:HiddenField ID="hdn_ID" runat="server" Value='<%# DataBinder.Eval(Container.DataItem, "ID") %>'/>
</ItemTemplate>
</asp:Repeater>
Code Behind :
protected void Chb_Changed(object sender, EventArgs e)
{
if (sender != null)
{
try
{
var hdnID = (HiddenField)checkBox.NamingContainer .FindControl("hf_ID");
if(hdnID != null)
{
string primaryFieldValue = hdnID.Value;
}
if (((CheckBox)sender).Checked)
{
Response.Write(((CheckBox)sender).Text + " is checked");
}
}
catch {
}
}
}

ASP.NET button does not run the related function

I have an UpdatePanel, in it a GridView, and in it a Repeater. There is a button to add comment. This button post backs but id does not run the function code behind. Here is my code
<updatepanel>
<gridview>
<repeater>
<asp:Button ID="kitapVarYorumEkle" runat="server"
CommandArgument='<%#Eval("id") %>'
CommandName='<%# GridView1.Rows.Count.ToString() %>'
Text="Yorum ekle" class="blueButton"
OnClick="kitapVarYorumEkle_Click" />
</repeater>
</gridview>
</updatepanel>
Code inside the js is:
protected void kitapVarYorumEkle_Click(object sender, EventArgs e)
{
kitapVarYorum temp = new kitapVarYorum();
if (Session["id"] != null)
{
temp.uyeId = Convert.ToInt32(Session["id"]);
}
Button btn = (Button)sender;
temp.kitapVarId = Convert.ToInt32(btn.CommandArgument);
string text = "";
GridViewRow row = GridView1.Rows[Convert.ToInt32(btn.CommandName)];
if (row != null)
{
TextBox txt = row.FindControl("txtYorum") as TextBox;
if (txt != null)
{
text = txt.Text;
}
}
temp.icerik = text;
var db = Tools.DBBaglanti();
db.kitapVarYorums.InsertOnSubmit(temp);
db.SubmitChanges();
// Page.Response.Redirect(Page.Request.Url.ToString(), true);
}
}
I have tried it outside the the controls and it works
Have you tried the ItemCommand approach?
<asp:Button
CommandArgument='<%#Eval("id") %>'
CommandName="yourCommandNameOfChoice"
Text="Yorum ekle"
ID="kitapVarYorumEkle"
class="blueButton" runat="server"
OnClick="kitapVarYorumEkle_Click" />
now add an ItemCommand event for your repeater:
protected void yourRepeater_ItemCommand(object source , RepeaterCommandEventArgs e)
{
switch(e.CommandName)
{
case "yourCommandNameOfChoice":
// Your Code Here
break;
}
}

Why is the footer-item not included in Repeater.Items?

I need to get a value from a textbox inside a FooterTemplate in the OnClick event of a button. My first thought was to loop through the items-property on my repeater, but as you can see in this sample, it only includes the actual databound items, not the footer-item.
ASPX:
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
Item<br />
</ItemTemplate>
<FooterTemplate>
Footer<br />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</FooterTemplate>
</asp:Repeater>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
Code-behind.cs:
protected void Page_Load(object sender, EventArgs e)
{
ListItemCollection items = new ListItemCollection();
items.Add("value1");
items.Add("value2");
Repeater1.DataSource = items;
Repeater1.DataBind();
}
protected void Button1_Click(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine(Repeater1.Items.Count);
}
This code will only output "2" as the count, so how do I get to reference my textbox inside the footertemplate?
From the MSDN documentation, the Items is simply a set of RepeaterItems based off the DataSource that you are binding to and does not include items in the Header or FooterTemplates.
If you want to reference the textbox, you can get a reference on ItemDataBound event from the repeater where you can test for the footer.
E.g.
private void Repeater_ItemDataBound(Object Sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Footer)
{
TextBox textBox = e.Item.FindControl("TextBox1") as TextBox;
}
}
You can find controls in the repeater. That will give you all the controls in the repeater (RepeaterItems collection). Now you can do something like this:
RepeaterItem footerItem=null;
foreach(Control cnt in Repeater1.Controls)
{
if(cnt.GetType() == typeof(RepeaterItem) && ((RepeaterItem)cnt).ItemType == ListItemType.Footer)
{
footerItem = cnt;
break;
}
}
The footer should be the last child control of the repeater so you can do something like..
RepeaterItem riFooter = Repeater1.Controls[Repeater1.Controls.Count - 1] as RepeaterItem;
if (riFooter != null && riFooter.ItemType == ListItemType.Footer) {
TextBox TextBox1 = riFooter.FindControl("TextBox1") as TextBox;
if (TextBox1 != null) {
TextBox1.Text = "Test";
}
}

Resources