我有一个aspx页面,我想要注入一个用户控件的引用。用户控件存储在单独的程序集中并在运行时加载。注入用户控件后,应将其加载到页面的控件集合中。
一切似乎工作正常,期望将控件添加到页面。没有错误,但控件的UI未显示。
的global.asax.cs
protected override Ninject.IKernel CreateKernel()
{
var modules = new INinjectModule[] { new MyDefaultModule() };
var kernel = new StandardKernel(modules);
// Loads the module from an assembly in the Bin
kernel.Load("ExternalAssembly.dll");
return kernel;
}
以下是外部模块在另一个程序集中的定义方式:
public class ExternalModule : NinjectModule
{
public ExternalModule() { }
public override void Load()
{
Bind<IView>().To<controls_MyCustomUserControlView>();
}
}
调试器显示当应用程序运行时,正在调用外部模块上的Load,并将依赖项注入页面。
public partial class admin_MainPage : PageBase
{
[Inject]
public IView Views { get; set; }
此时尝试将视图(此处为用户控件)添加到页面时,不会显示任何内容。这与Ninject创建用户控件的方式有关吗?加载的控件似乎有一个空的控件集合。
在aspx页面内
var c = (UserControl)Views;
// this won't show anything. even the Control collection of the loaded control (c.Controls) is empty
var view = MultiView1.GetActiveView().Controls.Add(c);
// but this works fine
MultiView1.GetActiveView().Controls.Add(new Label() { Text = "Nice view you got here..." });
最后是视图/用户控件:
public partial class controls_MyCustomUserControlView : UserControl, IView
{
}
它只包含一个标签:
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MyCustomUserControlView.ascx.cs" Inherits="controls_MyCustomUserControlView" %>
<asp:Label Text="Wow, what a view!" runat="server" />
答案 0 :(得分:2)
能够通过使用用户控件作为资源调用Page.LoadControl来实现此功能。
Page.LoadControl(typeof(controls_controls_MyCustomUserControlView),null)不起作用,但是Page.LoadControl(“controls_MyCustomUserControlView.ascx”)会这样做。
由于控件位于外部程序集中,首先按照http://www.codeproject.com/KB/aspnet/ASP2UserControlLibrary.aspx
所述创建VirtualPathProvider和VirtualFile自定义VirtualPathProvider将用于检查用户控件是否位于外部程序集中,VirtualFile(用户控件)将作为资源从程序集返回。
接下来设置Ninject模块以加载用户控件:
public override void Load()
{
//Bind<IView>().To<controls_MyCustomUserControlView>();
Bind<IView>().ToMethod(LoadControl).InRequestScope();
}
protected IView LoadControl(Ninject.Activation.IContext context)
{
var page = HttpContext.Current.Handler as System.Web.UI.Page;
if (page != null)
{
//var control = page.LoadControl(typeof(controls_MyCustomUserControlView), null);
var control = page.LoadControl("~/Plugins/ExternalAssembly.dll/MyCustomUserControlView.ascx");
return (IView)control;
}
return null;
}
“插件”只是用于在VirtualPathProvider中确定控件是否位于另一个程序集中的前缀。
如果您的用户控件具有命名空间,请确保在LoadControl中为控件名称添加前缀。另一件事是确保使用CodeBehind而不是CodeFile,因为ASP.NET将尝试加载CodeBehind文件。
<%@ Control Language="C#" AutoEventWireup="true"
CodeBehind="~/MyCustomUserControlView.ascx.cs" Inherits="controls_MyCustomUserControlView" %>