Frage

Also, das ist, was wir tun wollen: Uns um einen generischen Web-Teil mit einem benutzerdefinierten Rahmen haben wollen und dann andere Webparts dynamisch laden (rahmenlos) in seinem Innern. Wäre dies überhaupt möglich ist, Sie denken? Ein bisschen wie Jan Tielens Smartpart , nicht nur für ASP.Net User Controls, sondern auch für andere Webparts .. .;)

Edit: Wir haben in der Lage, dies jetzt zu tun. Die Lösung war eigentlich ziemlich einfach. Schauen Sie sich den Code:

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

So einfach ist das ... Wir auch Reflexion verwenden, um die webparts als XML usw. zu speichern, aber das ist nebensächlich.

War es hilfreich?

Lösung 2

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

Dieser Code muss einiges zu erklären ... Bitte entschuldigen Sie mich, wenn es nicht kompilieren läßt, ich ein gutes Stück von dem ursprünglichen Code entfernen musste, war es sehr Implementierung spezielle Sachen. Ich habe nicht die „config“ Klasse entweder gezeigt, es ist nur ein Container für die Konfiguration von webparts, nur ein Bündel von Eigenschaften. Es gibt 2 Ausgaben Ich möchte näher erörtern:

  1. parentWebPartGuid - Dies ist die Guid (UniqueId?) Des Hosting webpart. Aus irgendeinem Grund haben wir „StorageKeyInternal“ auf diesen Wert gesetzt, mithilfe von Reflektion (es ist ein Privatbesitz). Sie können möglicherweise mit nicht einstellen es weg, aber zumindest für die Mehrheit der webparts hatten wir es zu setzen.

  2. config.Properties - Dies ist der Konfigurationswert (wir setzten sie in einer benutzerdefinierten XML-Datei, aber fühlen Sie sich frei, dies zu erhalten von überall). Es kann ein wenig aussehen wie dieser ..

In unserem Rahmen wir Sachen wie dynamische Eigenschaftswerte auch usw. unterstützen, aber das ist für einen anderen Tag ... Hoffe das alles Sinn macht und jemand helfen kann.

Andere Tipps

Das glaube ich nicht so. Ich habe versucht, dieses eine Weile zurück, und es beschwerten sich über nur in der Lage zu sein WebPartZone Artikel in Seite Init hinzuzufügen. Ich denke, durch die Zeit, es ist erhalten Sie Ihre „Container“ zu initialisieren WebPart es zu spät ist mehr Zonen hinzuzufügen, da die Halte Seite wurde bereits initialisiert.

Es gibt (mindestens) zwei Möglichkeiten, dies zu tun. Iframe HTML-Element verwenden, oder einfach nur einen div, deren Inhalt durch JavaScript geändert wird (wahrscheinlich mit Ajax)

[HINWEIS] Meine Antwort ist generisch (dh. Auf Web-Design-Seite), ich habe keine Ahnung, wie es in Ihrem technischen Kontext, vielleicht soll ich diese Antwort löscht ...

Keine Chance auf die Quelle für die WebPartFactory Klasse bekommen ist da? Oder vielleicht ein bisschen mehr Informationen über sie? Pseudo-Code vielleicht? Wenn ein benutzerdefinierte Web-Teil in der Galerie ist, könnte es auf die gleiche Art und Weise Bezug genommen werden, wie RSSViewer ist richtig? Ich bin nur nicht sicher, wie man über das, was Sie hier gemacht haben, und ich möchte sehr viel besser verstehen, wie dies zu tun.

Danke!

Wenn ein Mangel eine benutzerdefinierte webpart in einem anderen benutzerdefinierten instanziiert webpart i den folgenden Code in der .ascx verwenden

<%@ Register tagPrefix="uc1" Namespace="Megawork.Votorantim.Intranet.Webparts_Intranet.LikeButton" Assembly="Megawork.Votorantim.Intranet, Version=1.0.0.0, Culture=neutral, PublicKeyToken=769156d154035602"  %>

Der Wert Namespace und der Assembly-Wert können von der Safecontrols Linie vom webconfig oder aus der Paketdatei (in manifest tab) kopiert werden:)

Wenn ich es instanziiert will dinammicaly (in der Tat) ist den folgenden Code in dem CS- verwenden

//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);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top