How can I move an user control into a panel? - c#

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

Related

How to access .ascx control from my aspx page

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" />

How to store multiple scroll positions for scrolling div element depending on active View in MultiView (asp.net webform

confusing title but the best way I can put it.
Basically I am currently using a single div with overflow:auto that contains different GridViews. The GridViews are swapped by using a MultiView with each indiviudal view containing a single GridView.
I would like to be able to store the scroll position of each view so that I can set the div's scroll position depending on the view that will be switched to.
Here is how my page is set up.
<div id="scrollingDiv" style="height:100%; overflow:auto;">
<div id="gridWrap">
<asp:UpdatePanel ID="UpdatePanel1" runat="server" RenderMode="Inline">
<ContentTemplate>
<asp:MultiView ID="MultiView1" runat="server">
<asp:View ID="view1" runat="server">
<asp:GridView ID="gridView1" runat="server">
</asp:GridView>
</asp:View>
<asp:View ID="view2" runat="server">
<asp:GridView ID="gridView2" runat="server">
</asp:GridView>
</asp:View>
</asp:Multiview>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</div>
So scrollingDiv will contain all the Views and will scroll for each one of the GridViews.
To switch between views I have a drop down connected to an
protected void DropDownList_SelectedIndexChanged(object sender, EventArgs e)
{
switch (DownList.SelectedItem.Value)
{
case "view1":
MultiView1.SetActiveView(view1);
break;
case "view2":
MultiView1.SetActiveView(view2);
break;
}
}
I have been looking around and can't quite find something specific to my case. I would like to be able to use just the one overflow div but would understand if I had to make a separate overflow div for each view.
Any help would be great,
Thanks.
jQuery and some hidden fields can help. Try this...
<asp:Hiddenfield ID="hdnCurrentView" runat="server"/>
<asp:Hiddenfield ID="hdnMultiView1Top" runat="server"/>
<asp:Hiddenfield ID="hdnMultiView2Top" runat="server"/>
On backend, i.e., in your CS file set the current view in hidden field...
protected void DropDownList_SelectedIndexChanged(object sender, EventArgs e)
{
switch (DownList.SelectedItem.Value)
{
case "view1":
MultiView1.SetActiveView(view1);
hdnCurrentView.Value = "View1";
break;
case "view2":
MultiView1.SetActiveView(view2);
hdnCurrentView.Value = "View2";
break;
}
}
Then in your jQuery ready function,
$().ready(function() {
//for storing scroll position of each view in respective hiddenfields
$(window).scroll(function () {
if ($("#hdnCurrentView").val() == "View1") {
$("#hdnMultiView1Top").val($(window).scrollTop());
}
else if ($("#hdnCurrentView").val() == "View2") {
$("#hdnMultiView2Top").val($(window).scrollTop());
}
});
//for restoring scroll position on page load i.e., ready function in jQuery
if ($("#hdnCurrentView").val() == "View1") {
$(window).scrollTop($("#hdnMultiView1Top").val());
}
else if ($("#hdnCurrentView").val() == "View2") {
$(window).scrollTop($("#hdnMultiView2Top").val());
}
});
This would maintain the vertical scroll position for each multiview. If you want to maintain horizontal scroll positions too, have hidden fields for each view & use jQuery function given below. Left to you as an excercise...
$(window).scrollLeft(value);
Happy Coding...;)

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

Lazy loading tabs with user controls

I want to use lazy loading of tabs in AJAX tab container. I have implemented it. But the problem that I am facing is that when I click a button or fire any event in that user control, it is not fired; nothing happens.
<asp:TabContainer runat="server" ID="TabContainerUp"
ActiveTabIndex="0" AutoPostBack="true" OnActiveTabChanged="TabContainerUp_ActiveTabChanged">
<asp:TabPanel ID="tab1" runat="server">
<HeaderTemplate>
<img src="images/uc1.png" alt="" />
</HeaderTemplate>
<ContentTemplate>
<asp:Panel ID="pnlUC1" runat="server">
</asp:Panel>
</ContentTemplate>
</asp:TabPanel>
<asp:TabPanel ID="tab2" runat="server">
<HeaderTemplate>
<img src="images/uc2.png" alt="" />
</HeaderTemplate>
<ContentTemplate>
<asp:Panel ID="pnlUC2" runat="server">
</asp:Panel>
</ContentTemplate>
</asp:TabPanel>
</asp:TabContainer>
codebehind:
protected void TabContainerUp_ActiveTabChanged(object sender, EventArgs e)
{
string tabName = TabContainerUp.ActiveTab.ID;
getActiveTab(tabName);
}
public void getActiveTab(string tabName)
{
UserControl uc;
//uc.
switch (tabName)
{
case "tab1":
pnlUC1.Controls.Clear();
uc = Page.LoadControl("~/Controls/UC1.ascx") as UserControl;
pnlUC1.Controls.Add(uc);
break;
case "tab2":
pnlUC2.Controls.Clear();
uc = Page.LoadControl("~/Controls/UC1.ascx") as UserControl;
pnlUC2.Controls.Add(uc);
break;
}
}
You need to recreate dynamically created controls on every postback in Page_Load at the latest, with the same ID as before. So you can load and add them to your panels in ActiveTabChanged, but you need to recreate them in the next postback in Page_Init/Page_Load. Therefor you need to store somewhere what to recreate (f.e. in Session).
But i assume that you're making things more complicated than necessary, you could simply create these UserControls even declaratively (on aspx) with an initial Visible state of false. Then you only need to switch visibility of the controls as necessary in ActiveTabChanged.
Note: invisible serverside webcontrols will not be rendered at all to the client and no ViewState will be saved. So there's no disadvantage in declaring them.
Lazy-Load does not mean that you create these controls as late as possible but it means that you databind them as late as possible. So never bind them to the database from page_load (f.e. in the UserControl), but only from methods that will be called when necessary from the page(here from ActiveTabChanged). Therefor you could implement a public method BindData in your UserControl UC1.
Here's a simple example:
switch (tabName)
{
case "tab1":
UC1_1.Visible = true;
UC1_1.BindData();
UC1_2.Visible = false;
break;
case "tab2":
UC1_1.Visible = false;
UC1_2.Visible = true;
UC1_2.BindData();
break;
}
and in your UserControl
public void BindData()
{
// put here all your databinding stuff
// that is in page_load now ...
}
This is probably the best tutorial on lazy-loading ajax TabPanels:
http://mattberseth.com/blog/2007/07/how_to_lazyload_tabpanels_with.html

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