How to access .ascx control from my aspx page - c#

I have following code in my ascx page
<%# Control Language="C#" AutoEventWireup="true" CodeFile="WebUserControl1.ascx.cs" Inherits="WebUserControl" %>
<li id="firstry" runat="server"> first </li>
And aspx page contains :
<uc:Spinner id="Spinner"
runat="server"
MinValue="1"
MaxValue="10" />
This simply prints my li into my aspx page.. but I want to access the the control in ascx so that i can apply inline or a css class into that control ..Can any one guide me ?

In the Control's code aside add:
public Control FirstTryControl
{
get { return firsttry; }
}
Then you can access it normally from the page...
Spinner.FirstTryControl.Styles.Add(...)
That is a brute force approach, you might want to consider adding properties specific to what you need instead. In the code aside add something like:
private _spinnerClass = string.empty;
public string SpinnerClass
{
get { return _spinnerClass; }
set { _spinnerClass = value; }
}
protected void Page_Render(o,e)
{
Spinner.Attributes.Add('class', _spinnerClass);
}
Then in the page you can define these properties right from the markup:
<uc:Spinner id="Spinner"
runat="server"
MinValue="1"
MaxValue="10"
SpinnerClass="green" />

Related

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 create a runat server DIV in the behind code ? ASP.NET & C#

I'm creating multiple DIVs according to database records at my C# behind code. How could I make them runat server ?
Thanks in advance ..
Create and add ASP.NET Panels.
The code
<asp:Panel id="abc" runat="server">
is exactly the same as if you do:
<div id="abc" runat="server">
They render the same, but it's the functionality with other WebControls that the Panel is most used, and the Panel web control gives you more control under code-behind as it exposes more properties.
If you want to access a DIV on serverside, you could also add runat="server". It will be created as HtmlGenericControl.
That's not necessary, just create a HtmlGenericControl and add it to the controls collection:
HtmlGenericControl div = HtmlGenericControl("div")
div.Id = "myid";
this.Controls.Add(div);
Use a custom control that pulls the data and renders it how you would like. Kind of like this:
public class MyDivControl : System.Web.UI.Control
{
private System.Data.DataTable tblMyResults;
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
// Get your Data (or do it on Page_Load if you'll need it more than once
if (tblMyResults != null && tblMyResults.Rows.Count > 0)
{
int iIndex = 0;
foreach (System.Data.DataRow rItem in tblMyResults.Rows)
{
writer.WriteLine("<div id=\"{0}_{1}\">", this.ClientID, iIndex++);
//Whatever content you want here using your rows.
writer.WriteLine("</div>");
}
}
}
}
Then just drop the control on the page where you want it to render.
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="default.aspx.cs" Inherits="Solution.Web.Presentation.pub._default" MasterPageFile="~/ui/master/main.master" %>
<%# Register TagPrefix="custom" Namespace="MyNameSpace" Assembly="MyProjectAssembly" %>
<asp:Content runat="server" ContentPlaceHolderID="cntMain">
<custom:MyDivControl runat="server" />
</asp:Content>
You can use Repeater Control
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<div id="box<%# Eval("ID")%>" runat="server"></div>
</ItemTemplate>
</asp:Repeater>
and bind data from codebehind

How can I move an user control into a panel?

On .aspx I have this :
<%# Register src="box/MyBox.ascx" tagname="MyBox" tagprefix="uc2" %>
<uc2:MyBoxID="MyBox1" runat="server" />
<asp:Panel ID="panelLeft" runat="server">
</asp:Panel>
<asp:Panel ID="panelRight" runat="server">
</asp:Panel>
and I'd like, on the aspx.cs, doing somethings like this :
if (condition)
{
panelLeft.Controls.Add(MyBox1);
}
else
{
panelRight.Controls.Add(MyBox1);
}
but seems I can't do it! Why? And how can I do it?
You'll have to use LoadControl to create the control server-side.
Control myBox1 = LoadControl("~/box/MyBox.ascx");
if (condition)
{
panelLeft.Controls.Add(myBox1);
}
else
{
panelRight.Controls.Add(myBox1);
}
If for some reason adding the control using LoadControl doesn't fit with the approach you want to take, you can achieve something similar by adding two copies of the user control into the markup in the two positions where you would like them. You can then toggle visibility in the code behind in your conditional logic.
For example, an ASPX like this:
<%# Register src="box/MyBox.ascx" tagname="MyBox" tagprefix="uc2" %>
<asp:Panel ID="panelLeft" runat="server">
<uc2:MyBoxID="MyBox1" runat="server" />
</asp:Panel>
<asp:Panel ID="panelRight" runat="server">
<uc2:MyBoxID="MyBox2" runat="server" />
</asp:Panel>
And then in the code behind you can toggle visibility:
MyBox1.Visible = condition;
MyBox2.Visible = !MyBox1.Visible;
However, you are then loading two different copies of the user control onto the page and your code would then have to know which user control to access, instead of always accessing 'MyBox1'. You might need a property in your code behind that hides that check for you, something like :
private MyBox MyBox{
get { return condition ? MyBox1 : MyBox2; }
}
if (condition)
{
this.panelLeft.Controls.Add(mybox1);
}
else
{
this.panelRight.Controls.Add(myBox1);
}

Can I pass a class instance to a custom user control via the front end of a page/control in ASP.Net?

I have a custom user control that I am adding to a page via the front end (not back). That customer user control has a property that is of the type of a custom class. I would like to set that property via the declaration of the user control on the front end.
Here's some code to help you understand what I'm talking about:
In the custom user control .cs:
public BaseTUDSectionControl parentSectionControl
{
get;
set;
}
And at the declaration of an instance of that user control:
<tud:TUDDropDown ID="tddAccountExecutive" runat="server" />
I would like to set the parentSectionControl property in the same line, like this:
<tud:TUDDropDown parentSectionControl=someClassInstance
ID="tddAccountExecutive" runat="server" />
where 'someClassInstance' is a class instance that does exist... yeah. I think I am going about this the wrong way, but I don't know how else to accomplish this. I don't want to do it on the back end for maintenance reasons as I'll have hundreds of similar user controls added all throughout my project.
Is anything like this possible, or am I smoking something?
No that's not possible. You can only set property of basic types (int, string, bool) etc. from the markup (what you call front-end). If you have a property which is to be set to an instance of a class, this has to be done in the code-behind (what you call back-end).
I'm not sure if/when Microsoft added this functionality to ASP.NET, but it is in fact possible to set a non-basic-type property in code-front:
TestPage.aspx:
<%# Page Language="C#" AutoEventWireup="true" CodeFile="TestPage.aspx.cs" Inherits="TestPage" %>
<%# Register Src="~/Control.ascx" TagPrefix="custom" TagName="Control" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>Test Page</title></head>
<body>
<custom:Control ID="TestControl" Items='<%# Items %>' runat="server" />
</body>
</html>
TestPage.aspx.cs:
using System;
using System.Collections.Generic;
using System.Web.UI;
public partial class TestPage : Page
{
protected void Page_Load(object sender, EventArgs e)
{
TestControl.DataBind();
}
protected List<string> Items = new List<string>() { "Hello", "world!", };
}
Control.ascx:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="Control.ascx.cs" Inherits="Control" %>
<asp:Repeater ID="Repeater" ItemType="System.string" runat="server">
<ItemTemplate>
<p><%# Item %></p>
</ItemTemplate>
</asp:Repeater>
Control.ascx.cs:
using System;
using System.Collections.Generic;
using System.Web.UI;
public partial class Control : UserControl
{
public List<string> Items { get; set; }
protected override void OnPreRender(EventArgs e)
{
Repeater.DataSource = Items;
Repeater.DataBind();
}
}
Note: it's important to bind the control from the page which sets the property. So you still need a line in code-behind, but you still reap the readability benefits of setting the property in code-front.

Manipulating a control in a child from the parent page

The answer is probably obvious but I have not seen anything I could use except the opposite - manipulating the parent from the child - so I'm posting new.
I have a shopping cart system I'm working on that my company purchased and I'm new to .NET so I may not even ask this properly.
My store has a page in the checkout portion that looks basically like this:
PaymentPage.ascx:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="PaymentPage.ascx.cs" Inherits="ConLib_PaymentPage" %>
<%# Register Assembly="CommerceBuilder.Web" Namespace="CommerceBuilder.Web.UI.WebControls" TagPrefix="cb" %>
<%# Register Src="~/Checkout/PaymentForms/CreditCardPaymentForm.ascx" TagName="CreditCardPaymentForm" TagPrefix="uc" %>
<ajax:UpdatePanel ID="PaymentAjax" runat="server">
<ContentTemplate>
On page controls, etc.
Then a checkbox saying they've read the terms and agree:
<div id="terms">
<asp:CheckBox ID="AgreeTerms" runat="server" Text="I agree to the Terms Of Service" CssClass="Terms" AutoPostBack="True" OnCheckedChanged="AgreeTerms_Clicked"/>
</div>
The task I want to accomplish is in the OnCheckedChanged event I want to enable or disable an imagebutton inside the CreditCardPaymentForm control.
That code looks like this:
<%# Control Language="C#" ClassName="CreditCardPaymentForm" EnableViewState="false" %>
<%# Register Assembly="CommerceBuilder.Web" Namespace="CommerceBuilder.Web.UI.WebControls" TagPrefix="cb" %>
<%# Register assembly="wwhoverpanel" Namespace="Westwind.Web.Controls" TagPrefix="wwh" %>
... a <script> block with some code and then HTML
<span class="TTAActionButton">
<br>
<asp:ImageButton ID="CreditCardButton" runat="server" ToolTip="Pay With Card" SkinID="TTAPlaceOrder" OnClick="CreditCardButton_Click" />
<asp:HiddenField runat="server" ID="FormIsSubmitted" value="0" />
<br /><br /><br />
</span>
I want to be able to turn the CreditCardButton on and off depending on whether the checkbox is checked. I would have a routine in the page codebehind like:
public void AgreeTerms_Clicked(object sender, EventArgs e)
{
if (AgreeTerms.Checked)
CreditCardButton.Enabled = false;
}
but every permutation of that I try has failed.
I have abbreviated the code but if I've left out too much please let me know.
Thanks for your help and if you assume I know nothing about .NET then double-thanks!
Jim
In the CreditCardPaymentForm control create a property that exposes the CreditCardButton visibility and than use that from the parent in the OnCheckedChanged function handler.
public bool ShowCreditCardButton
{
get { return CreditCardButton.Visable; }
set { CreditCardButton.Visable = value; }
}
Does CreditCardPaymentForm include a PaymentPage.ascx? That is, does the form 'use' the PaymentPage user control?
if so, your best bet it is to publish an event on PaymentPage that is raised by the checking of the checkbox:
public void AgreeTerms_Clicked(object sender, EventArgs e)
{
if (AgreeTerms.Checked)
OnTermsAgreed();
}
private void OnTermsAgreed()
{
// raise TermsAgreed event
var evt = TermsAgreed;
if (null != evt)
evt(this, EventArgs.Empty);
}
public event EventHandler TermsAgreed;
Then CreditCardPaymentForm subscribes to that event and 'does its thing' which in your case is to enable the button it knows about.

Categories