Laden...

UserControl mit Childs darstellen

Erstellt von TiltonJH vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.125 Views
TiltonJH Themenstarter:in
87 Beiträge seit 2006
vor 13 Jahren
UserControl mit Childs darstellen

Ich würde gerne etwas in der art zum laufen bringen

irgendwo in der Page:


<uc:ModalPopupPanel runat="server" ID="test" >
	<asp:Label ID="TestLabel" text="TestLabelText" runat="server" />
	<asp:Button Text="text" runat="server" />
</uc:ModalPopupPanel>

das uc (UserControl)
code behind:


[PersistChildren(true)]
[ParseChildren(false)]
public partial class ModalPopupPanel : UserControl
{
	protected void Page_Load(object sender, EventArgs e)
	{
	}
}

asp.net


<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ModalPopupPanel.ascx.cs" Inherits="WebServer.Utilities.ModalPopupPanel" %>
<div class="divModalBackground">
</div>
<asp:AlwaysVisibleControlExtender runat="server" TargetControlID="panelModalPopup" HorizontalSide="Center" VerticalSide="Middle" />
<asp:Panel runat="server" ID="panelModalPopup" CssClass="divModalPopup">XXX</asp:Panel>

Die Controls in der Page sollen an der Stelle wo die XXX im asp des UC stehen auftauchen.

  1. Geht das überhaupt?
  2. Wenn ja wie?

Bemerkung;

der code als solches funzt, nur eben die child controls (in der page spezifiziert) werden nich angezeigt.

MfG

Tilton

"In der Informatik geht es genauso wenig um Computer wie in der Astonomie um Teleskope."
Edsger W. Dijkstra

The Humble Programmer by Edsger W. Dijkstra

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo,

dafür muss Dein UserControl einen <asp:Placeholder> bekommen, in dem die Controls über ein Template instanziert werden können.

Guck dir mal das hier an:
How to: Create Templated ASP.NET User Controls

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

TiltonJH Themenstarter:in
87 Beiträge seit 2006
vor 13 Jahren

So richtig Schlauch werde ich aus dem Beispiel nicht. Dort wird eine eigene Klasse im page_init erstellt und in den placeholder geschoben.

Ich möchte aber das auf der Page (.aspx) einem bestimmten UserControl (.ascx) Chlidren zu gewiesen werden können, die dann an ein vorherbestimmten Stelle innerhalb des UserControls erstellt werden. Das Beispielt hilft da nicht wirklich. ich weis das die Children auch dem UserControl.Controls property zu gewiesen werden. aber angezeigt werden sie nirgens und schon gar nich wo ich die gerne hätte. 🙁

MfG

Tilton

"In der Informatik geht es genauso wenig um Computer wie in der Astonomie um Teleskope."
Edsger W. Dijkstra

The Humble Programmer by Edsger W. Dijkstra

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo,

was in dem Beispiel innerhalb der MessageContainer-Klasse passiert, kannst Du weitgehend ignorieren. Die wird dort nur als NamingContainer benutzt.

Wichtig ist folgendes (ich hab :

[ TemplateContainer(typeof(MessageContainer)) ]
[ PersistenceMode(PersistenceMode.InnerProperty) ]
public ITemplate MessageTemplate {
    get 
    { 
        return messageTemplate; 
    }
    set 
    { 
        messageTemplate = value; 
    }
}

// wenn Du einen neuen NamingContainer willst, dann auch folgendes
// das kannst DU Dir aber ggf. sparen (siehe unten):
public class MessageContainer: Control, INamingContainer
{
}

und dann das



// wenn Du eine Klasse für den NamingContainer erstellt hast:
            MessageContainer container = new MessageContainer();
            messageTemplate.InstantiateIn(container);
            PlaceHolder1.Controls.Add(container);

// wenn Du Dir den Container sparen willst, könntest Du mal versuchen:
            messageTemplate.InstantiateIn(PlaceHolder1);

Du kannst natürlich auch mehrere Templates definieren, und für jedes einen Placeholder erstellen. Diese Placeholder kannst Du dann schon im UserControl anordnen.

[ TemplateContainer(typeof(MyControl)) ]
[ PersistenceMode(PersistenceMode.InnerProperty) ]
public ITemplate MyContentArea1{
    get 
    { 
        return myContentArea1;
    }
    set 
    { 
        myContentArea1= value; 
    }
}
[ TemplateContainer(typeof(MyControl)) ]
[ PersistenceMode(PersistenceMode.InnerProperty) ]
public ITemplate MyContentArea2{
    get 
    { 
        return myContentArea2; 
    }
    set 
    { 
        myContentArea2= value; 
    }
}

In der Page würde das dann so aussehen:


<uc:MyControl>
  <MyContentArea1>
    // Inhalt des ersten PlaceHolder
  </MyContentArea1>
  <MyContentArea2>
    // Inhalt des zweiten PlaceHolder
  </MyContentArea2>
</uc:myControl>

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

TiltonJH Themenstarter:in
87 Beiträge seit 2006
vor 13 Jahren

Ich habs gelöst bekommen. Nicht unbedingt sehr elegant, aber es funzt. Wenn jmd verbessungspotensial sieht immer her damit.

Ich weis das mein ModalPopupPanel 6 Einträge in Controls hat, jedes weitere bekommt es von der Page. Und die verschiebe ich einfach in mein Panel (also da wo die hin sollen). 😁

Mir wäre es lieber, ich könnte gleich alle Children in das Panel umlenken. Wenn ich nur wüsste wie.

Meine Code:


<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ModalPopupPanel.ascx.cs" Inherits="WebServer.Utilities.ModalPopupPanel" %>
<div class="divModalBackground">
</div>
<asp:AlwaysVisibleControlExtender runat="server" TargetControlID="panelModalPopup" HorizontalSide="Center" VerticalSide="Middle" />
<asp:Panel runat="server" ID="panelModalPopup" CssClass="divModalPopup" />


using System;
using System.Web.UI;

namespace WebServer.Utilities
{
	[PersistChildren(true)]
	[ParseChildren(false)]
	public partial class ModalPopupPanel : UserControl
	{
		protected void Page_Load(object sender, EventArgs e)
		{
		}

		void Page_Init()
		{
			const int controlCount = 6;
			if (this.Controls.Count > controlCount)
			{
				for (int i = controlCount; i < this.Controls.Count;)
				{
					this.panelModalPopup.Controls.Add(this.Controls[i]);
					this.Controls.RemoveAt(i);
				}
			}
		}

	}
}

EDIT:

@MarsStein, das werde ich mir auch gleich noch mal aunschaun. thx

MfG

TiltonJH

"In der Informatik geht es genauso wenig um Computer wie in der Astonomie um Teleskope."
Edsger W. Dijkstra

The Humble Programmer by Edsger W. Dijkstra

3.170 Beiträge seit 2006
vor 13 Jahren

Hallo,

wenn Du alles sowieso in das Panel stecken willst, könntest Du beim InstantiateIn(...)-Aufruf IMO sogar direkt das Panel übergeben, und Dir auf diese Weise auch noch den PlaceHolder sparen 8)

Gruß, MarsStein

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

TiltonJH Themenstarter:in
87 Beiträge seit 2006
vor 13 Jahren

Jup, so hab ich das auch gemacht.


<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ModalPopupPanel.ascx.cs" Inherits="WebServer.Utilities.ModalPopupPanel" %>
<div class="divModalBackground">
</div>
<asp:AlwaysVisibleControlExtender runat="server" TargetControlID="panelModalPopup" HorizontalSide="Center" VerticalSide="Middle" />
<asp:Panel runat="server" ID="panelModalPopup" CssClass="divModalPopup" />


using System;
using System.Web.UI;

namespace WebServer.Utilities
{
	public partial class ModalPopupPanel : UserControl
	{
		protected void Page_Load(object sender, EventArgs e)
		{
		}

		[TemplateContainer((typeof(UserControl)))]
		[PersistenceMode(PersistenceMode.InnerProperty)]
		public ITemplate PanelControls
		{
			get;
			set;
		}

		void Page_Init()
		{
			if (this.PanelControls != null)
			{
				this.PanelControls.InstantiateIn(this.panelModalPopup);
			}
		}

	}
}

Böld is die stelle mit

[TemplateContainer((typeof(UserControl)))]

Das hier ein Typ angegeben werden muss. UserControl funzt auch mit normalen Control.
zb:


<uc:ModalPopupPanel runat="server" ID="modalPopupPanelTest" Visible="false" >
	<PanelControls>
		<asp:Button runat="server" ID="buttonWech" Text="wech..." OnClick="buttonWech_Click" />
	</PanelControls>
</uc:ModalPopupPanel>

Aber was auf diese weise nicht mehr geht is, dass ich die Child-Controls direkt aus der Page ansprechen kann. In meiner Lösung geht das.

Deswegen werde ich woll erstmal bei meiner bleiben. Schön wäre es zu wissen mit wechler Methode die Child-Controls zur laufzeit in das UserControl geschoben werden. Da könnte man die dann einfach in das Panel umleiten.
Dein Mein UserControl soll sich von außen wie ein normales Panel benehmen.

MfG

Tilton

"In der Informatik geht es genauso wenig um Computer wie in der Astonomie um Teleskope."
Edsger W. Dijkstra

The Humble Programmer by Edsger W. Dijkstra

TiltonJH Themenstarter:in
87 Beiträge seit 2006
vor 13 Jahren

Mein Lösung:

Aber immer noch etwas schmutzig, da im C#-Code genau eingestellt werden muss wie viele Controls das ModalPopupPanel selber hat (siehe "const int controlCount = 5;").


<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ModalPopupPanel.ascx.cs" Inherits="WebServer.Utilities.ModalPopupPanel" %>
<div class="divModalBackground">
</div>
<asp:AlwaysVisibleControlExtender runat="server" TargetControlID="panelModalPopup" HorizontalSide="Center" VerticalSide="Middle" />
<asp:Panel runat="server" ID="panelModalPopup" CssClass="divModalPopup" />


using System.Web.UI;

namespace WebServer.Utilities
{
	[PersistChildren(true)]
	[ParseChildren(false)]
	public partial class ModalPopupPanel : UserControl
	{
		protected void Page_Init()
		{
			const int controlCount = 5;
			while (this.Controls.Count > controlCount)
			{
				this.panelModalPopup.Controls.Add(this.Controls[controlCount]);
			}
		}

	}
}

"In der Informatik geht es genauso wenig um Computer wie in der Astonomie um Teleskope."
Edsger W. Dijkstra

The Humble Programmer by Edsger W. Dijkstra