ASP.net User control not recognized - c#

I am trying to add a user control dynamically to an asp.net web page.
user control code:
<%# Control ClassName="CustomParameterView" %>
<script runat="server">
public string Value { get; set; }
public string Description { get; set; }
public string Name { get; set; }
private void Input_OnTextChanged(object sender, EventArgs e)
{
Value = Input.Text;
}
</script>
<div class="form-horizontal">
<div class="form-group">
<label class="col-sm-2 control-label" id="DisplayName"></label>
<div class="col-sm-3">
<asp:TextBox ID="Input" runat="server" CssClass="form-control" OnTextChanged="Input_OnTextChanged" />
</div>
</div>
</div>
I have added the register line in the .aspx file:
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="PerCHW.Valkyrie.Server.WebApplication._Default" %>
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<%# Reference Control="CustomParameterView.ascx" %>
...
The problem is that this:
var control = (CustomParameterView) LoadControl("CustomParameterView.ascx");
does not compile.
I also saw people trying ti add the ASP. before the UC name but that does not work as well...
What am I doing wrong?

It looks like you are not adding the control to a PlaceHolder.
In the .aspx page add a PlaceHolder:
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
And then add the Control to the PlaceHolder in code behind:
var control = (CustomParameterView)LoadControl("~/CustomParameterView.ascx");
PlaceHolder1.Controls.Add(control);
Make sure this code is called every time the page is loaded, so don't put it inside a !IsPostBack check or the Control will be gone after PostBack.

Related

How to FindControl on content page from dynamic User Control

I am getting a null reference exception when trying to FindControl on a button. I have a shopping cart setup where I have a content page (.aspx) based on a master page. On the content page, there is a placeholder control in which I am dynamically adding user controls (one control per product, each with an 'add to cart' button inside it).
When the user clicks button to add item to cart, I can add it to the cart successfully, then I am counting the number of items in the cart and if more than 1, trying to show the 'checkout' button, or if none in the cart hide it.
I am using FindControl, but getting a null reference error. Why can't it find the checkout button? My current code is below:
MASTER PAGE (template.Master):
<%# Master Language="C#" AutoEventWireup="true" CodeBehind="template.master.cs" Inherits="OUWP.template" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head runat="server"></head>
<body>
<form id="form1" runat="server">
<asp:ContentPlaceHolder ID="m_cph_body" runat="server"></asp:ContentPlaceHolder>
</form>
</body>
</html>
CONTENT PAGE (shop.aspx)
<%# Page Title="" Language="C#" MasterPageFile="~/template.Master" AutoEventWireup="true" CodeBehind="shop.aspx.cs" Inherits="OUWP.shop" %>
<%# MasterType VirtualPath="~/template.Master" %>
<asp:Content ID="Content2" ContentPlaceHolderID="m_cph_body" runat="server">
<asp:PlaceHolder ID="Catalogue" runat="server">
<!-- this is where the user controls are dynamically generated-->
</asp:PlaceHolder>
<asp:Panel ID="pnl_Basket" runat="server">
<div>
<asp:LinkButton ID="lbtnCheckout" runat="server">Continue to Checkout</asp:LinkButton>
</div>
</asp:Panel>
</asp:Content>
USER CONTROL PAGE (PurchasableProduct.ascx)
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="PurchasableProduct.ascx.cs" Inherits="OUWP.CustomControls.PurchasableProduct" %>
<asp:UpdatePanel ID="udpBody" runat="server">
<ContentTemplate>
<asp:Panel ID="pnlPurchasableProduct" runat="server">
<asp:LinkButton ID="lbtnAddLine" runat="server" OnClick="lbtnAddLine_Click"></asp:LinkButton>
</asp:Panel>
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="lbtnAddLine" />
</Triggers>
</asp:UpdatePanel>
USER CONTROL CODE BEHIND (PurchasableProduct.ascx.cs)
protected void lbtnAddLine_Click(object sender, EventArgs e)
{
// try to find checkout button on parent page of control
System.Web.UI.Page page = (System.Web.UI.Page)this.Page;
LinkButton Target1 = (LinkButton)page.FindControl("lbtnCheckout");
// count the items in the cart (saved in session variable)
DataTable dt = (DataTable)Session["varDataTableCart"];
Int32 ItemCount = 0;
Int Line Quantity = 0;
foreach (DataRow dr in dt.Rows)
{
Int32 LineQuantity = Convert.ToInt32(dt.Rows[dt.Rows.IndexOf(dr)]["Quantity"].ToString());
ItemCount = ItemCount + LineQuantity;
}
// if 1 or more items in cart, try to make button visible
if (ItemCount > 0)
{
Target1.Visible = true;
}
// otherwise no items in cart, so try to hide checkout button
else
{
Target1.Visible = false;
}
}
I have also tried to get at it through the master page using the code below but that didn't work either:
MasterPage mp1 = (MasterPage)page.Master;
LinkButton Target1 = (LinkButton)mp1.Page.FindControl("lbtnCheckout");
Ok so by pure luck I tried this code and it worked and found my button. Using 'parent' of the current control.
LinkButton Target1 = (LinkButton)this.Parent.FindControl("lbtnCheckout");

Web User Controls in different Project

I put some self made Web User Controls in a seperate Project "WebControls" and now want to reuse them from another Project
My Control consists of:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="TestControl.ascx.cs" Inherits="WebControls.TestControl" %>
<asp:Label ID="lblTest" runat="server" ></asp:Label>
<asp:TextBox ID="textBox" runat="server" Width="" />
<asp:HiddenField ID="hiddenFieldId" runat="server" />
with Code Behind:
namespace WebControls
{
public partial class TestControl : System.Web.UI.UserControl
{
public Unit Width
{
get { return textBox.Width; }
set { textBox.Width = value; }
}
public string SelectedId
{
get { return hiddenFieldId.Value; }
set { hiddenFieldId.Value = value; }
}
public string SelectedText
{
get { return textBox.Text; }
set { textBox.Text = value;}
}
protected void Page_Init(object sender, EventArgs e)
{
}
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
I bind it into a Webpage in the other project like that:
<%# Page Title="ToDo Serien" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="True" CodeBehind="RecurringToDos.aspx.cs" Inherits="TestAccess.RecurringToDos" %>
<%# Register Assembly="WebControls" Namespace="WebControls" TagPrefix="aci" %>
<asp:Content runat="server" ID="FeaturedContent" ContentPlaceHolderID="FeaturedContent">
<section class="featured">
<div class="content-wrapper">
<hgroup class="title">
<h1><%: Title %>.</h1>
<h2>Serienelement</h2>
<aci:TestControl ID="aceRule" runat="server" Width="300" />
<asp:Button ID="btnSend" runat="server" OnClick="btnSend_Click" />
</hgroup>
</div>
....
When I now start the page it throws a Reference Null Exception in following line:
set { textBox.Width = value; }
becuase textBox = NULL
Seems my Control is not properly initiated.
What am I doing wrong?
How can I fix that?
If you want to reuse a ascx user control across multiple projects, you should copy ascx file to the consumer project and register the tag this way:
<%# Register TagPrefix="uc" TagName="UserControl1" Src="~/UserControl1.ascx" %>
As an example, you can follow these steps:
Create a new web project name it WebUserControls
Add a Web Forms User Control and name it UserControl1
<%# Control Language="C#" AutoEventWireup="true"
CodeBehind="UserControl1.ascx.cs" Inherits="WebUserControls.UserControl1" %>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
and in code behind add:
public string Text
{
get { return TextBox1.Text; }
set { TextBox1.Text = value; }
}
In the consumer project, add a reference to the project containing the ascx user control.
Copy .ascx file of control into the consumer project.
Note: You don't need to add the file to the project, but the physical file should exist in the path which you used as Src in registerting the tag.
In the page which you want to use the control, add this:
<%# Register TagPrefix="uc" TagName="UserControl1" Src="~/UserControl1.ascx" %>
Use the control this way:
<uc:UserControl1 runat="server" Text="UserControl1" />
Note
If you want to not copy ascx file, you can use Web Forms Server Control which doesn't rely on ascx files. Then for using those custom controls, it's enough to register them:
<%# Register Assembly="WebUserControls" Namespace="WebUserControls" TagPrefix="uc" %>
This answer relies on a great post by Scott Guthrie in this topic: Creating and Using User Control Libraries

How to make user control load once?

I have one user control,named as "SocialShareElements", which's purpose is to share the page content/image into FaceBook.
I utilized this user control in my Index page.
I called this user control in a "IF" condition, within Index.aspx.
The pseudo code is like:
<%
if (Request.IsSecureConnection)
{
%>
<div class="deal-detail-head tzsg-margin-bottom-med">
<MyControl:SocialShareElements ID="SocialShareElements1" runat="server"/>
</div>
<div class="clear-both"></div>
<%
}
else
{
%>
<div class="deal-test bottom-small">
<MyControl:SocialShareElements ID="SocialShareElements" runat="server"/>
</div>
<%
}
%>
When I test the FBShare function in https://developers.facebook.com/tools/debug/og/object/, it showed failed becuase I loaded "SocialShareElements" twice, and this makes meta data of "SocialShareElements" double in Index.aspx.
My question is how to adjust the logic of utilizing "SocialShareElements" in Index.aspx, to make it only be loaded once.
Thank you.
You can achieve this from code-behind.
Modify your div on your aspx page to be available from server side:
<div id="socialShare" runat="server">
</div>
In your code-behind:
protected void Page_Load(object sender, EventArgs e)
{
if(Request.IsSecureConnection)
{
SocialShareElements shareElement = LoadControl("SocialShareElements.ascx") as SocialShareElements;
socialDiv.Controls.Add(shareElement);
}
}

Cookie not displaying on second page load

What I am trying to accomplish is to create a cookie so that after you click a save button, leave the page and then come back to the page, the value of the cookie should be displayed in a label at the top of the page welcoming the user back to the page.
Here is the code I am using.
<%# page language="C#" %>
<%# Import Namespace="System.Data" %>
<%# Import Namespace="System.Data.OleDb" %>
<script language="C#" runat="server">
String welcomeBackName;
void Page_Load(Object sender, System.EventArgs e)
{
if (Page.IsPostBack==true)
{
HttpCookie RUcookie = new HttpCookie("RUcookie");
lblMessage.Text = txtfirstname.Text.Substring(0,1).ToLower() + txtlastname.Text.ToLower() + "#radford.edu";
RUcookie.Value = "Welcome " +txtfirstname.Text +" "+ txtlastname.Text;
RUcookie.Expires = DateTime.Now.AddHours(1);
Response.Cookies.Add(RUcookie);
if(RUcookie != null)
{
welcomeBackName = Request.Cookies["RUcookie"].Value;
welcomeBack.Text = welcomeBackName;
}
}
}
</script>
<html>
<form id=form1 runat="server">
<br>
<ASP:Label id="welcomeBack" Text="" size="60" runat="server"/>
<br>
<br>
<br>
First Name: <asp:TextBox id="txtfirstname" size="20" runat="server"/><br>
<br>
Last Name : <asp:TextBox id="txtlastname" size="20" runat="server"/><br>
<br>
<ASP:Button id="butSave" Text="Save" Autopostback=true runat="server"/>
<br>
<br>
Email: <asp:Label id="lblMessage" size="80" forecolor=Blue runat="server"/><br>
</form>
</html>
Few things wrong.
You said you want this to happen when the user leaves the page and comes back. By definition, you won't be in a postback. That'd be a fresh load of the page. Instead of checking if it's a postback, you should simply check to see if the cookie exists.
The other thing is that IsPostBack is by definition, a boolean. You don't need to check if it's equivalent to true. It's either true or false.

Unable to get textbox even when ID is defined

I am currently creating a page that a user will be able to input information and on submit it should save this information to a text file, however I seem to be unable to obtain the textbox as it appears to be undefined even when an ID is set on it, could someone please explain what I am doing wrong? As it seems to be working correctly with my btnSave method.
Backend C#:
public partial class Green_FreeShipping : System.Web.UI.Page
{
private static readonly string FILE_PATH = "~/TextFiles/Notes.txt";
private void GetNote()
{
using (TextReader tr = new StreamReader(MapPath(FILE_PATH)))
{
txtNote.Text = tr.ReadToEnd();
}
}
private void SaveNote()
{
using (TextWriter tw = new StreamWriter(MapPath(FILE_PATH)))
{
tw.Write(txtNote.Text);
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
this.GetNote();
}
}
protected void btnSave_Click(object sender, EventArgs e)
{
this.SaveNote();
this.GetNote();
}
}
ASP.NET code:
<%# Page Language="C#" MasterPageFile="~/admin/masters/admin.master" autoeventwireup="true" inherits="TextBox_ReadWriteToTextFile" Title="Green & Free shipping amounts" codefile="~/admin/bespoke/Green-FreeShipping.aspx.cs"%>
<%# Register TagPrefix="web" Assembly="website.Web" Namespace="website.Web" %>
<%# Register TagPrefix="sales" Assembly="website.site.Web" Namespace="website.site.Web.Sales" %>
<%# Register TagPrefix="ecom" Namespace="website.site.Web" Assembly="website.site.Web" %>
<asp:Content ID="TitleContent" ContentPlaceHolderID="TitlePlaceHolder" runat="Server">
<title>Shopfront - Green and Free shipping amounts</title>
</asp:Content>
<asp:content id="Content1" contentplaceholderid="ContentPlaceHolder1" runat="Server">
<div style="margin-bottom: 20px;">
<asp:textbox id="txtNote" runat="server" rows="5" textmode="MultiLine" width="200px" />
</div>
<asp:button id="btnSave" runat="server" onclick="btnSave_Click" text="Save" />
</asp:content>
Your asp should inherit 'Green_FreeShipping' so that the c# can have access to the controls contained in it.

Categories