I am working on asp.net c# . I am trying to find the header control in c# . But I am getting object not set to an instance of an object . My code is
public void R1_ItemDataBound(Object Sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Header)
{
HtmlGenericControl ulSubNav2 = (HtmlGenericControl)e.Item.FindControl("da-sliders");
ulSubNav2.Style.Add("background", "transparent url('DesktopModules/DNAiusParallelSlider/Images/waves.gif') repeat 0% 0%");
ulSubNav2.Style.Add("width", "100%");
ulSubNav2.Style.Add("height", "400px");
}
}
relevant HTML Code
<HeaderTemplate>
<div id="da-sliders" class="da-slider" OnItemDataBound="R1_ItemDataBound">
</HeaderTemplate>
this is because the system failed to find the control with the name you specified.
Try to add a "runat" tag to the div like this :
<div id="da-sliders" class="da-slider" OnItemDataBound="R1_ItemDataBound" **runat="server"**>
Now in your ItemDataBound you have access to the div item in the HeaderTemplate.
Related
In this post I wanted to figure out how to create dynamically created textboxes in C# Visual Studio.
Adding additional textboxes to aspx based on xml
However, when I try to call the ID of these dynamically created textboxes later in my code to figure out what text the user entered into them, I am getting an error that says these IDs do not exist in the current context. Does anyone know how I would be able to call these?
credit to Adding additional textboxes to aspx based on xml
Here is my entire code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml.Linq;
namespace WebApplication4
{
public partial class WebForm15 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsCallback)
{
//credit to https://stackoverflow.com/questions/44076955/adding-additional-textboxes-to-aspx-based-on-xml#comment75336978_44078684
const string xml = #"<Number>
<Num>1</Num>
<Num>2</Num>
<Num>3</Num>
</Number>";
XDocument doc = XDocument.Parse(xml);
int i = 0;
foreach (XElement num in doc.Root.Elements())
{
TextBox box = new TextBox
{
ID = "dynamicTextBox" + i,
Text = num.Value,
ReadOnly = false
};
divToAddTo.Controls.Add(box);
divToAddTo.Controls.Add(new LiteralControl("<br/>"));
i++;
}
}
}
protected void BtnGetValues_Click(object sender, EventArgs e)
{
IList<string> valueReturnArray = new List<string>();
foreach (Control d in divToAddTo.Controls)
{
if (d is TextBox)
{
valueReturnArray.Add(((TextBox)d).Text);
}
}
//valueReturnArray will now contain the values of all the textboxes
}
}
}
Here is aspx:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm15.aspx.cs" Inherits="WebApplication4.WebForm15" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>
<body>
<form id="form1" runat="server">
<div id="divToAddTo" runat="server" />
<asp:Button runat="server" ID="BtnGetValues" Text="GetValues" OnClick="BtnGetValues_Click" />
</form>
</body>
</html>
Figured it out!!! Here is what I found after scouring the internet for hours
Solution:
When using dynamic controls, you must remember that they will exist only until the next postback.ASP.NET will not re-create a dynamically added control. If you need to re-create a control multiple times, you should perform the control creation in the PageLoad event handler ( As currently you are just creating only for first time the TextBox using Condition: !IsPostabck ). This has the additional benefit of allowing you to use view state with your dynamic control. Even though view state is normally restored before the Page.Load event, if you create a control in the handler for the PageLoad event, ASP.NET will apply any view state information that it has after the PageLoad event handler ends.
So, Remove the Condition: !IsPostback, So that each time the page Loads, The TextBox control is also created. You will also see the State of Text box saved after PageLoad handler completes. [ Obviously you have not disabled ViewState!!! ]
Example:
protected void Page_Load(object sender, EventArgs e)
{
TextBox txtBox = new TextBox();
// Assign some text and an ID so you can retrieve it later.
txtBox.ID = "newButton";
PlaceHolder1.Controls.Add(txtBox);
}
Now after running it, type anything in text box and see what happens when you click any button that causes postback. The Text Box still has maintained its State!!!
I'm trying to figure out how to find a "div" which is in my main .aspx page from a class, is this possible? If so how? I've tried the code below but is not working
HtmlGenericControl step1 = (HtmlGenericControl)Page.FindControl("step1")
I know this is the way I would do it in the code behind file but in this case I want to do it from a class file.
Thank you in advance.
Basically what I'm trying to accomplish is this, I have multiple divs in my page all of the have runtat="server" visible="false" when certain criteria is met I want to be able to change the visible="true". I have this scenario in multiple pages so I want to be able to create a Class and check for the conditions there and through this way make the div visible or un-visible
The div element must have the runat="server" attribute:
<body>
<form id="form1" runat="server">
<div id="step1" runat="server"></div>
</form>
</body>
Now, you can find the control with a method in a separated class, which is called from the code behind class of the page:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Class1 class1 = new Class1();
class1.FindDiv(this);
}
}
Separated class:
public class Class1
{
public HtmlGenericControl FindDiv(Page page)
{
HtmlGenericControl step1 = (HtmlGenericControl)page.FindControl("step1");
return step1;
}
}
If you use ASP Panel instead of a div u can access it and Panel renders as div. If u give runat="server" to a div u should be able to access it.
You cannot do that if it is not a server side control..
If it is a HTML control you need to set runat="server" attribute to the div to find it in code behind..
Try
HtmlGenericControl div = (HtmlGenericControl)this.FindControl("div1");
Note : In order to make this code work, you need to have runat="server" property at aspx page.
Title is a bit of a mouthful, but I'm a bit stuck on this issue.
I have a search result page with has a custom control that has a Repeater. The ItemTemplate in the repeater is a PlaceHolder so I can construct the Item in a particular format; more specifically, I have a string of 'diseases' that come in the form of Disease1|disease2|disease3 and need to be given links for each disease.
Now for some code:
The following is the SearchResultControl.ascx
<asp:Panel ID="SearchResultPanel" runat="server" ScrollBars="Auto">
<asp:Repeater ID="Repeater1" runat="server"
onitemcreated="Repeater1_ItemCreated"
onitemcommand="Repeater1_ItemCommand">
<ItemTemplate>
<asp:PlaceHolder ID="ItemTemplatePlaceHolder" runat="server">
</asp:PlaceHolder>
</ItemTemplate>
<SeparatorTemplate>
<tr>
<td colspan="6"><hr /></td>
</tr>
</SeparatorTemplate>
</asp:Repeater>
</asp:Panel>
The code behind: SearchResultControl.ascx.cs
protected void Repeater1_ItemCreated(object sender, RepeaterItemEventArgs e)
{
if (e.Item.DataItem != null)
{
PlaceHolder placeHolder = e.Item.FindControl("ItemTemplatePlaceHolder") as PlaceHolder;
Control searchResultItem = Page.LoadControl("SearchResultItem.ascx");
DataRow row = (e.Item.DataItem as DataRowView).Row;
if (row != null)
{
string diseaseState = row["DiseaseStates"] as string;
searchResultItem.GetType().GetProperty("DiseaseStates").SetValue(searchResultItem, diseaseState, null);
placeHolder.Controls.Add(searchResultItem);
}
}
}
(Full disclosure, I got this idea from this question)
The SetValue calls the DiseaseStates property in SearchResultItem which in turn calls the following method to build the links, set the text, and the events:
private void BuildDiseaseStateLabels(string diseaseStates)
{
PlaceHolder placeHolder = FindControl("DiseaseStatePlaceHolder") as PlaceHolder;
string[] diseaseStateSplit = diseaseStates.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
int count = diseaseStateSplit.Length;
foreach (string diseaseState in diseaseStateSplit)
{
LinkButton diseaseStateLink = new LinkButton();
diseaseStateLink.Text = diseaseState;
//diseaseStateLink.Click += new EventHandler(OnDiseaseStateLinkClick);
diseaseStateLink.CommandArgument = "<%# Eval(\"PatientID\")+ \";\" + Eval(\"PatientStatus\")+ \";\" + Eval(\"Age\")+ \";\" + Eval(\"DiseaseStates\")%>";
diseaseStateLink.CommandName = "OnDiseaseStateLinkClick";
//diseaseStateLink.Command += new CommandEventHandler(OnDiseaseStateLinkClick);
placeHolder.Controls.Add(diseaseStateLink);
if (count != 0)
{
Label splitLabel = new Label();
splitLabel.Text = "|";
placeHolder.Controls.Add(splitLabel);
}
}
}
This is the layout for the SearchResultItem
<div id="SearchResultItemDiv" class="MainSearchResultItem">
<asp:PlaceHolder ID="DiseaseStatePlaceHolder" runat="server">
</asp:PlaceHolder>
</div>
Initially I tried setting the Click event, but that doesn't work at all. I then set the CommandArgument and CommandName but that didn't seem to do the trick. I figured the Command event might need to be set, but again, no luck. I should note that when a link is clicked the Repeater1_ItemCreated in SearchResultControl.ascx.cs is called. But since there is no data in e.Item.DataItem is null and I lose the results.
In one of the questions regarding the same issue, it was suggested that the OnItemCommand be added, but even that doesn't get called.
I also read A Stumper of an ASP.NET Question and A Stumper of an ASP.NET Question: SOLVED!, to no avail.
What could I possibly be doing wrong? All of the correct event hookups seem there, I'm checking for IsPostBack and not doing DataBind() again. blaaargharaggh
Help is always greatly appreciate.
I believe you're running into this issue because the LinkButton controls are recreated too late in the page lifecycle. You have to remember that when the page is posted back, the control technically does not exist anymore, so the event handler cannot be fired.
If you can recreate the LinkButton controls somewhere before the Page_Load event is reached, like OnInit for example, everything should work fine.
For simple pages the above usually works very well, but there are circumstances where recreating controls during OnInit requires a lot of overhead, such as storing counters or arrays in ViewState so you can keep track of the controls that need to be recreated after postback. In these situations I would suggest taking a look at the DynamicControlsPlaceHolder by Denis Bauer. This control is capable of persisting dynamic controls without any addtional code required, which is pretty awesome.
Here's a link to the latest version:
http://www.denisbauer.com/ASPNETControls/DynamicControlsPlaceholder.aspx
The problem might be that you're not doing the DataBind() again.
Because you're building the buttons on the fly, when the page post backs, the buttons haven't been created and are unable to work out which click event it should be firing.
Try getting rid of the IsPostBack check, so each time the page loads, you're re-build the repeater.
The above is the code in my .aspx page.
How this can be added from code behind dyanmically?
<ul runat="server" id="1">
<li>abc
<ul runat="server" id="2">
<li>3</li>
<li>2</li>
</ul>
</li>
</ul>
you can take the analogy of the tutorial given in this link :
http://neimke.blogspot.com/2011/01/create-delicious-user-interface-for.html
it worked for me - It dynamically adds the list items using the given code below using jquery .. check it pout ...
<li id="tagInputListItem"><input class="tagInput" id="tagInput" /></li>
You can put a PlaceHolder in your .aspx and give it an id, then use that id in code behind page and add controls to that placeholder.
For more information you can see in here.
And if you're really sure about "runat=server" attribute maybe this post of mine it's useful (here)
If you need clarifications give me a feedback.
You must use the "InnerHtml" property of "sidebarmenu1" control.
protected void Page_Load(object sender, EventArgs e)
{
this.loadHtml();
}
So you can generate every list item code and add it to the InnerHtml:
private loadHtml()
{
this.sidebarmenu1.InnerHtml = GetListHtml().ToHtmlString();
}
And a little example for this GetListHtml:
public string GetListHtml()
{
StringBuilder htmlBuilder = new StringBuilder();
htmlBuilder.AppendLine("<li>Flat");
htmlBuilder.Append("<ul runat="server" id="sidebarmenu2">");
htmlBuilder.AppendLine("<li>Flat 1`enter code here`</li>");
htmlBuilder.Append("<li>Flat 2</li></ul>");
return htmlBuilder.ToString();
}
This GetListHtml method can call to a DAL or load data from any other place... use a foreach to load every item...
You can use ASP Literal to populate data from back-end code
eg. if you have literal with id ltrNavigation
protected void Page_Load(object sender, EventArgs e)
{
ltrNavigation.text = "";
if (!IsPostBack)
{
ltrNavigation.text += "<ul id='sidebarmenu1'>";
ltrNavigation.text += "<li><a href='#'>Flat</a></li>";
ltrNavigation.text += "</ul>";
}
}
Trying to set the value of a literal user control on my child master page via the code behind of the same master page.
Here is example of the code I am using:
Global.master
<form id="form1" runat="server">
<div>
<asp:ContentPlaceHolder id="GlobalContentPlaceHolderBody" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
Template.master (child of Global.master)
<asp:Content ID="TemplateContentBody" ContentPlaceHolderID="GlobalContentPlaceHolderBody" Runat="Server">
<asp:Literal ID="MyLiteral1" runat="Server"></asp:Literal>
<p>This is template sample content!</p>
<asp:ContentPlaceHolder ID="TemplateContentPlaceHolderBody" runat="server">
</asp:ContentPlaceHolder>
Template.master.cs
protected void Page_Load(object sender, EventArgs e)
{
MyLiteral1.Text = "Test";
}
ContentPage.aspx
< asp:Content ID="ContentBody" ContentPlaceHolderID="TemplateContentPlaceHolderBody" Runat="Server">
</asp:Content>
Once I am able to achieve this, I will also need to be able to access content on the global and template master pages via content pages.
If I understand your scenario you want to have your content pages access items from your master pages. If so, you'll need to setup a property to expose them from your master page, and in your content page you can setup a MasterType directive.
Take a look at this post for an example.
Found a working solution. In the template.master (nested child master), I had to put the code in OnLoad event.
protected override void OnLoad(EventArgs e)
{
MyLiteral1.Text= "<p>MyLiteral1 Successfully updated from nested template!</p>";
base.OnLoad(e);
}
Very strange...
Basically, I am using the global master as the page that has code shared on every page, then I will have various nested pages to suit each website section. For the navigation nested template, I want to be able to show if the user is logged in and how many items in shopping cart.
If there is a better way to achieve this, I am open to suggestions.
EDIT: This is my answer when I thought you were trying to access a control on the child master from the parent master code behind.
You can use a recursive findControl function:
protected Control FindControlRecursive(string id, Control parent)
{
// If parent is the control we're looking for, return it
if (string.Compare(parent.ID, id, true) == 0)
return parent;
// Search through children
foreach (Control child in parent.Controls)
{
Control match = FindControlRecursive(id, child);
if (match != null)
return match;
}
// If we reach here then no control with id was found
return null;
}
Then use this code in your master page:
protected void Page_Load(object sender, EventArgs e)
{
//EDIT: if GlobalContentPlaceHolderBody isn't visible here, use this instead:
//Control c = FindControlRecursive("MyLiteral1", Page.FindControl("GlobalContentPlaceHolderBody"));
Control c = FindControlRecursive("MyLiteral1", GlobalContentPlaceHolderBody);
if(c != null)
((Literal)c).Text = "Test";
}