sharepoint - español - powerapps ejemplos
Posible cargar un elemento web dentro de otro? (5)
Entonces, esto es lo que queremos hacer: queremos tener un elemento web genérico con un marco personalizado a su alrededor y luego cargar dinámicamente otros elementos web (sin marco) dentro de él. ¿Sería posible que esto sea posible? Un poco como el SmartPart de Jan Tielens , pero no para los controles de usuario de ASP.Net, sino para otros elementos web ...;)
Editar: Hemos podido hacer esto ahora. La solución fue bastante simple. Mira el código:
public class WebPartWrapper : System.Web.UI.WebControls.WebParts.WebPart {
protected override void CreateChildControls() {
Panel pnl = new Panel();
this.Controls.Add(pnl);
WebPart dynamicPart = WebPartFactory.CreateWebPart("RSSViewer");
pnl.Controls.Add(dynamicPart);
}
}
Tan fácil como eso ... También utilizamos la reflexión para almacenar las partes web como Xml, etc., pero eso no viene al caso.
Hay (al menos) dos formas de hacer esto: usar elemento HTML iframe, o simplemente un div cuyo contenido es modificado por JavaScript (probablemente con Ajax).
[NOTA] Mi respuesta es genérica (es decir, en el lado del diseño web), no tengo idea de cómo es en su contexto técnico, así que tal vez debería eliminar esta respuesta ...
No lo creo. Intenté esto hace un tiempo y se quejó de que solo se podían agregar elementos de WebPartZone en Page Init. Creo que para cuando se inicialice su WebPart "contenedor" es demasiado tarde para agregar más zonas ya que la página de espera ya se ha inicializado.
¿No hay posibilidad de obtener la fuente para la clase WebPartFactory? ¿O tal vez un poco más de información al respecto? Pseudo código tal vez? Si un elemento web personalizado está en la galería, se puede hacer referencia a él de la misma forma que RSSViewer es correcto. No estoy muy seguro de cómo hacer lo que has hecho aquí, y me gustaría mucho mejor entender cómo hacerlo.
¡Gracias!
public class WebPartWrapper : System.Web.UI.WebControls.WebParts.WebPart {
protected override void CreateChildControls() {
Panel pnl = new Panel();
this.Controls.Add(pnl);
var factory = new WebPartFactory()
WebPart dynamicPart = factory.CreateWebPart("RSSViewer", this.Guid);
pnl.Controls.Add(dynamicPart);
}
}
public class WebPartFactory {
public WebPart CreateWebpart(string webpartName, Guid parentWebPartGuid)
{
var config = ConfigurationFactory.LoadConfiguration(webpartName);
Assembly webPartAssembly = Assembly.Load(config.Assembly);
Type webPartType = webPartAssembly.GetType(config.Class);
object actualWebPart = Activator.CreateInstance(webPartType);
foreach (var item in config.Properties)
{
PropertyInfo webPartProperty = webPartType.GetProperty(item.Name);
object webPartPropertyValue = Convert.ChangeType(itemValue, Type.GetType(item.Type));
if (!String.IsNullOrEmpty(item.Value))
webPartProperty.SetValue(actualWebPart, webPartPropertyValue, null);
}
RunMethod("set_StorageKeyInternal", actualWebPart, new object[] { parentWebPartGuid });
return actualWebPart as WebPart;
}
private void RunMethod(string methodName, object objectInstance, object[] methodParameters)
{
BindingFlags flags = BindingFlags.Instance | BindingFlags.Public |
BindingFlags.NonPublic;
Type t = objectInstance.GetType();
MethodInfo m = GetMethod(t, methodName, flags);
if (m != null)
{
m.Invoke(objectInstance, methodParameters);
}
}
private MethodInfo GetMethod(Type instanceType, string methodName, BindingFlags flags)
{
MethodInfo m = instanceType.GetMethod(methodName, flags);
if (m != null)
{
return m;
}
if (instanceType.GetType() == typeof(object) || instanceType.BaseType == null)
{
return null;
}
return GetMethod(instanceType.BaseType, methodName, flags);
}
}
Este código necesita algunas explicaciones ... Disculpe si no compila, tuve que eliminar un poco del código original, era algo muy específico de la implementación. Tampoco he mostrado la clase "config", es solo un contenedor para la configuración de partes web, solo un conjunto de propiedades. Hay dos cuestiones que me gustaría analizar con más detalle:
parentWebPartGuid: este es el Guid (UniqueId?) del sitio web de alojamiento. Por alguna razón, tenemos que establecer "StorageKeyInternal" a este valor, utilizando la reflexión (es una propiedad privada). Posiblemente puede salirse con la suya sin configurarlo, pero al menos para la mayoría de las partes web tuvimos que configurarlo.
config.Properties: estos son los valores de configuración (los configuramos en un archivo .xml personalizado, pero no dude en obtenerlo desde cualquier lugar). Se puede ver un poco como esto ..
En nuestro marco también apoyamos cosas como los valores de propiedades dinámicas, etc., pero eso es para otro día ... Espero que todo esto tenga sentido y pueda ayudar a alguien.
Cuando quiero instanciar un webpart personalizado dentro de otro webpart personalizado, utilizo el siguiente código en .ascx
<%@ Register tagPrefix="uc1" Namespace="Megawork.Votorantim.Intranet.Webparts_Intranet.LikeButton" Assembly="Megawork.Votorantim.Intranet, Version=1.0.0.0, Culture=neutral, PublicKeyToken=769156d154035602" %>
El valor del espacio de nombres y el valor de ensamblaje se pueden copiar desde la línea SafeControls desde el archivo webconfig o desde el archivo del paquete (en la pestaña de manifiesto) :)
Cuando quiero instanciarlo dinamicamente (de hecho) es usar el siguiente código en el archivo .cs
//This is the namespace of the control that will be instantiated dinamically
string type = "My.Custom.Namespace.WebpartToBeAdded.WebpartToBeAdded";
// Instantiate the control dinamically based on his type
System.Web.UI.WebControls.WebParts.WebPart genericWP = (System.Web.UI.WebControls.WebParts.WebPart)Activator.CreateInstance(Type.GetType(type));
// sets the page to the genericWP (i dont know if this is required)
genericWP.Page = this.Page;
// Note: if you want to call custom methods of the dinamically instantiated controls (like a custom load method) you will need to create an interface and make your dinamically instantiated webpart implement it. You will need to do it in that file that have the following code: private const string _ascxPath @"~/_CONTROLTEMPLATES/...". Then you can do the following
//IMyInterface ig = (IMyInterface)genericWP;
//ig.MyCustomLoadMethod(someParam);
// Adds the controls to a container, an asp panel by example.
panelDinamicControls.Controls.Add(genericWP);