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

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";
}
}

Related

Get value of gridview.selected.row[] with visible property = 'false'

Hi from this field in my gridview, I'd like to pass the id value when the select command field is clicked, but i don't want to have the id field visible so I have the visible property set to false; however, when I pass it on the SelectedIndexChanged event the value is "" yet when the visible property is set to "true" the text value passes fine. What is the correct way to do this?
<asp:BoundField DataField="Project_ID" Visible="false"/>
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
String ProjID = GridView1.SelectedRow.Cells[10].Text;
}
Try this:
.aspx
<asp:Gridview id="GridView1" runat="server" DataKeyNames="Project_ID" />
.cs
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
if(gridView.SelectedDataKey != null)
{
var selectedId = GridView1.SelectedDataKey.Value;
}
}
Here you'll find more info about DataKeys in Gridviews: http://msdn.microsoft.com/de-de/library/system.web.ui.webcontrols.gridview.selecteddatakey(v=vs.110).aspx
I have done something like this in winform maybe can help you. That is what i used
int rowindex = dataGridView1.CurrentRow.Index;
string ProjID= dataGridView1.Rows[rowindex].Cells[10].Value.ToString();
you could use HiddenField inside your gridView ItemTemplate to keep the ID and use it in onrowcommand event, like below:
.aspx
<asp:GridView ID="gridProject" runat="server"
onrowcommand="gridProject_RowCommand">
<Columns>
<ItemTemplate>
<asp:HiddenField ID="hidProjectID" runat="server"
Value='<%# ((DataRowView)Container.DataItem)["Project_ID"] %>' />
<asp:Button ID="btnProject" runat="server" Text="use pro id"
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>"
CommandName="DoSomething"></asp:Button>
</ItemTemplate>
</Columns>
</asp:GridView>
aspx.cs
protected void gridProject_RowCommand(object sender, GridViewCommandEventArgs e)
{
int index = 0;
GridViewRow gridRow;
GridView grid = sender as GridView;
try
{
switch (e.CommandName)
{
case "DoSomething":
index = Convert.ToInt32(e.CommandArgument);
row= gridProject.Rows[index];
string Id = ((HiddenField)row.FindControl("hidProjectID")).Value;
//do whatever you want here
break;
// and you can have as many commands as you want here
}
}
catch { //display error }
}

Findcontrol in Listview returns null

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;
}
}

Getting values from textbox in the repeater in button click event

I have a TextBox in a repeater that is populated from the database in the ItemDataBound event. When I tried to get the text inside the TextBox in a Button_Click event I found the TextBox.Text empty. How can I get the Text?
foreach (RepeaterItem repeated in repEdit.Items)
{
DropDownList drp = (DropDownList)FindControlRecursive(repeated, "drpdown");
TextBox txt = (TextBox)FindControlRecursive(repeated, "txt");
CheckBox chk = (CheckBox)FindControlRecursive(repeated, "chk");
if (drp != null && !string.IsNullOrEmpty(drp.Attributes["ID"]))
{
loc.GetType().GetProperty(drp.Attributes["ID"].Split('#')[0] + "ID").SetValue(loc, int.Parse(drp.SelectedValue), null);
}
if (txt != null && !string.IsNullOrEmpty(txt.Attributes["ID"]))
{
if (txt.Attributes["ID"].Contains("#int"))
{
loc.GetType().GetProperty(txt.Attributes["ID"].Split('#')[0]).SetValue(loc, int.Parse(txt.Text), null);
}
else if (txt.Attributes["ID"].Contains("#decimal"))
{
loc.GetType().GetProperty(txt.Attributes["ID"].Split('#')[0]).SetValue(loc, decimal.Parse(txt.Text), null);
}
else
{
loc.GetType().GetProperty(txt.Attributes["ID"].Split('#')[0]).SetValue(loc, txt.Text, null);
}
}
if (chk!=null && !string.IsNullOrEmpty(chk.Attributes["ID"]))
{
loc.GetType().GetProperty(chk.Attributes["ID"].Split('#')[0]).SetValue(loc, chk.Checked, null);
}
}
HTML
<asp:Repeater ID="repEdit" runat="server" OnItemDataBound="repEdit_ItemDataBound">
<ItemTemplate>
<asp:Label ID="lblName" runat="server" Visible="false"></asp:Label>
<asp:TextBox ID="txt" runat="server" Visible="false"></asp:TextBox>
<asp:CheckBox ID="chk" runat="server" Visible="false" />
<asp:DropDownList ID="drpdown" runat="server" Visible="false">
</asp:DropDownList>
<br />
</ItemTemplate>
</asp:Repeater>
Here is the itemdatabound event
protected void repEdit_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Label name = e.Item.FindControl("lblName") as Label;
TextBox text = e.Item.FindControl("txt") as TextBox;
CheckBox chk = e.Item.FindControl("chk") as CheckBox;
DropDownList drp = e.Item.FindControl("drpdown") as DropDownList;
Button but = e.Item.FindControl("butEdit") as Button;
//butEdit.Visible = true;
if (but != null)
{
but.Visible = true;
}
if (e.Item.ItemType == ListItemType.Item)
{
KeyValuePair<string, Dictionary<int, string>> kvp = (KeyValuePair<string, Dictionary<int, string>>)e.Item.DataItem;
if (name != null)
{
if (kvp.Key.Contains("#datetime"))
{
return;
}
name.Visible = true;
name.Text = kvp.Key.Split('#')[0].ToString();
}
if (kvp.Key.Contains("#int") || kvp.Key.Contains("#decimal"))
{
text.Visible = true;
text.ID = kvp.Key;
text.EnableViewState = true;
text.Attributes["ID"] = kvp.Key;
text.Text = kvp.Value[0].ToString();
if (kvp.Key.Split('#')[0] == "ID")
{
text.Enabled = false;
}
}
Here is your Repeater. It has a PlaceHolder and Button.
<asp:Repeater ID="rpNotifications" runat="server"
OnItemDataBound="rpNotifications_ItemDataBound">
<ItemTemplate>
<asp:PlaceHolder ID="commentHolder" runat="server"></asp:PlaceHolder>
<asp:Button runat="server" ID="btnComment"
Text="Comment" CssClass="btn blue"
OnClick="btnComment_Click" CommandArgument='<%# Eval("id") %>' />
</ItemTemplate>
</asp:Repeater>
The button has the command argument set as the Id of the data I am binding to it.
Next here is where you need to Bind your Repeater. If you don't Bind it in the Page_Init the resulting values in the dynamically created controls will be lost.
protected void Page_Init(object sender, EventArgs e)
{
rpNotifications.DataSource = {datasource-here}
rpNotifications.DataBind();
}
And here is why (Image from: http://msdn.microsoft.com/en-us/library/ms972976.aspx)
Dynamically Create Control on ItemDataBound
You will need to add the textbox to the placeholder as this is the only way to dynamically assign an ID to the control.
protected void rpNotifications_ItemDataBound(object sender,
RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item
|| e.Item.ItemType == ListItemType.AlternatingItem)
{
Common.Models.Item item = (Common.Models.Item)e.Item.DataItem;
// Create new Control
TextBox txtComment = new TextBox();
txtComment.ID = String.Format("txtComment{0}", item.id.ToString());
// Ensure static so you can reference it by Id
txtComment.ClientIDMode = System.Web.UI.ClientIDMode.Static;
// Add control to placeholder
e.Item.FindControl("commentHolder").Controls.Add(txtComment);
}
}
Get Value On Button Click
Now you need to create the event handler for the button and get the resulting value
protected void btnComment_Click(object sender, EventArgs e)
{
// This is the ID I put in the CommandArgument
Guid id = new Guid(((Button)sender).CommandArgument);
String comment = String.Empty;
// Loop through the repeaterItems to find your control
foreach (RepeaterItem item in rpNotifications.Controls)
{
Control ctl = item.FindControl(
String.Format("txtComment{0}", id.ToString()));
if (ctl != null)
{
comment = ((TextBox)ctl).Text;
break;
}
}
}
Try to get ASP.Net controls using below code
DropDownList drp = (DropDownList)repeated.FindControl("drpdown");
TextBox txt = (TextBox)repeated.FindControl("txt");
CheckBox chk = (CheckBox)repeated.FindControl("chk");
Then you can get values from there respective properties.

View state on dropdown control

<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" UseSubmitBehavior="false"
OnClick="Button1_Click" OnClientClick="this.disabled = true; this.value = 'Submitting...'; "
Text="Click Me…" /></div>
<asp:DropDownList ID = "dListFruits" runat ="server" EnableViewState ="true"></asp:DropDownList>
protected void Page_Load(object sender, EventArgs e)
{
ArrayList aList = new ArrayList();
aList.Add("Apples");
aList.Add("Oranges");
if (!Page.IsPostBack)
{
dListFruits.DataSource = aList;
dListFruits.DataBind();
TextBox1.Text = "Hi";
}
}
protected void Button1_Click(object sender, EventArgs e)
{
}
When i had a break point in a button click event , this peice of statement "dListFruits.DataSource" shows null while debugging. I thought view state will be applied before load event triggered. But when i see the page items are appended into the dropdown list. So view state will be applied just before render?
Just check out the Items collection of the dropdownlist. Viewstate stores the items collection of dropdownlist control.

How to make visible a column of gridview?

I am using Gridview.In this i have 2 columns i.e. department and emailID.In this gridview department is bind from database and showed in linkbutton in gridview.
I want to do that when i clicked on thst dept linkbutton it make visible the column emailID.
How can i do this?Plaese guide me..
Thanks in advance.
Here is My Grid:
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lnkbtnDept" runat="server" Text='<%#Bind("Department")%>' OnClick="lnkbtnTitle_Click" ></asp:LinkButton>
</ItemTemplate>
<ItemStyle HorizontalAlign="Left" Width="50%" />
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Panel ID="pnlN24" runat="server" Visible="false">
<asp:Label ID="lblTotal" runat="server" Width="30" Text="abc"></asp:Label>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
You have to handle the events of GridView control especially RowCommand.
public class Demo
{
public string Dept { get; set; }
public string Email { get; set; }
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
List<Demo> list = new List<Demo>()
{
new Demo() { Dept="A", Email="a#a.com" },
new Demo() { Dept="B", Email="b#b.com" },
};
GridView1.DataSource = list;
GridView1.DataBind();
}
}
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "cmd")
{
GridViewRow row = (e.CommandSource as LinkButton).NamingContainer as GridViewRow;
Label email = row.Cells[1].FindControl("email") as Label;
email.Visible = true;
}
}
Understanding that you will make visible all the cells in the column for all the rows, you can handle the OnClick event of the dept button. For example.
<asp:LinkButton ID="lnkDept" OnClick="LinkButton_Click" runat="server" Text="Department" />
Code behind:
protected void LinkButton_Click(Object sender, EventArgs e)
{
gridView1.Columns[1].Visible=true;
}
Where gridView.Column[1] is your email column.
its not possible to make cell visible when column's visibility property set to false. so for showing only adjacent cell visible .
you can use the only one column of type template field and then make a table in that template field and set the td of email to visible false and on row command of grid as the previous answers making that lable visible you should make your td visible .
protected void lnkbtnTitle_Click(object sender, EventArgs e)
{
GridViewRow gvrow = ((LinkButton)sender).Parent.Parent as GridViewRow;
Panel pnlN24 = (Panel)gvrow.FindControl("pnlN24");
pnlN24.Visible = true;
}
It is very simple , the above code will work.
We have to find in which row the LinkButton is Clicked , which we can get from the
the following code. Once you get the GridViewRow then find the control in that row and make it Visible
GridViewRow gvrow = ((LinkButton)sender).Parent.Parent as GridViewRow;
As we know that
Control <--- Cell <-- GridViewRow <-- GridView
For Eg:
LinkButton <--- Cell <-- GridViewRow <-- GridView
GridViewRow is Parent to Cell and Cell is Parent to the Control inside the Cell (Panel)
function validateColors(id) {
var grid = document.getElementById("GridView1");
var label = grid.rows[id].cells[6].children[2];
grid.rows[id].cells[6].children[2].style.visibility = "visible";
grid.rows[id].cells[6].children[2].style.visibility = "hidden";
}

Resources