可以将Web部件加载到另一个内部吗?

noo*_*yte 11 sharepoint web-parts

所以,这就是我们想要做的事情:我们想要一个带有自定义框架的通用Web部件,然后在其中动态加载其他Web部件(无框架).你觉得这有可能吗?有点像Jan Tielens SmartPart,只适用于ASP.Net用户控件,但适用于其他Web部件...;)

编辑:我们现在已经能够做到这一点.解决方案实际上非常简单.看看代码:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这很容易...我们也使用反射将webparts存储为Xml等,但这不是重点.

noo*_*yte 4

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);
    } 
}
Run Code Online (Sandbox Code Playgroud)

这段代码需要一些解释...如果它不能编译,请原谅,我不得不删除相当多的原始代码,这是非常特定于实现的东西。我也没有显示“config”类,它只是一个用于配置 webpart 的容器,只是一堆属性。我想更详细地讨论两个问题:

  1. ParentWebPartGuid - 这是托管 Web 部件的 Guid(UniqueId?)。由于某种原因,我们必须使用反射(它是私有属性)将“StorageKeyInternal”设置为该值。您可以不设置它,但至少对于大多数 Web 部件,我们必须设置它。

  2. config.Properties - 这是配置值(我们在自定义 .xml 文件中设置它们,但可以随意从任何地方获取它)。它看起来有点像这样..

在我们的框架中,我们还支持动态属性值等内容,但那是另一天的事了......希望这一切都有意义并且可以帮助某人。