嵌套用户控件在可视 Web 部件中不起作用

Posted

技术标签:

【中文标题】嵌套用户控件在可视 Web 部件中不起作用【英文标题】:Nested User Controls not working within Visual Web Part 【发布时间】:2012-03-03 08:19:00 【问题描述】:

尽管我尽了最大的努力,但我的雇主仍要求我使用 Sharepoint 开发一个 Web 应用程序,而不是一些有用的东西。

我在 Visual Studio 2010 的 Sharepoint 项目中将用户控件嵌入到 Visual Web 部件时遇到问题。我正在使用以下步骤(请注意,此代码只是我所拥有的内容的概要 - 作为我目前的真实代码包含足够多的脏话让我终身禁止 ***):

    创建一个新的空 Sharepoint 项目。

    将用户控件添加到项目(位于 ControlTemplates 中),名为 MyControl.ascx

MyControl.ascx:

<asp:TextBox runat="server" ID="txtStuff" />

MyControl.ascx.cs:

public class MyControl : UserControl 

    public int Property  get; set; 

    protected void Page_Load(object sender, EventArgs e) 
    
        txtStuff.Text = "I hate you sharepoint";
    

    将可视 Web 部件添加到项目 MyWebPart.ascx

MyWebPart.ascx

<%@ Register TagPrefix="c" TagName="MyControl" src="~/_controlTemplates/MyControl" %>
<c:MyControl runat="server" ID="mycontrol" />

当我到达这一点时,我没有为 MyControl 获得任何智能感知,这很可能是因为 VS 不知道 .ascx 文件的存在。我还在控件名称下看到绿色波浪线,让我知道它不存在。但是,我仍然可以将项目部署到我的 Sharepoint 服务器本身,并且一切正常。

但是,当我需要与控件本身进行任何有用的交互时,这就会崩溃:

MyWebPart.ascx.cs

protected void Page_Load(object sender, EventArgs e) 
    mycontrol.Property = 1234;

这会产生“System.Web.UI.UserControl 不包含'Property'的定义并且没有扩展方法...'的错误。designer.cs 文件确实将控件指定为 UserControl,而不是它的真正的类型。

由于现在这会产生构建错误,因此我无法将项目部署到 Sharepoint 服务器,因此我无法真正解决这个智能感知问题。

我发现这是非常不一致的行为;有时会出现智能感知,具体取决于项目当前是否部署到服务器。但是,我无法采取一组可预测的步骤来使开发环境处于工作状态。

有什么想法吗?我尝试过的事情:

    右键单击 Web 部件的 ASCX 并单击“打开方式...”并选择“使用编码”选项。没有效果。

    使用部署和收回的应用程序以及关闭和重新打开 .ascx 文件、解决方案和 Visual Studio 本身的各种组合进行开发。有时有效,有时无效。

    禁用了项目的“调试后自动收回”选项(从知识库文章中推荐)。没有效果。

【问题讨论】:

你有解决办法吗?我被困在同一页面上。 【参考方案1】:

创建可视化 Web 部件时,您可以“免费”获得控件。创建一个 VWP 并将您的内容粘贴到该控件中,而不是事先创建一个。

如果您想使用已创建的控件,请创建一个常规 Web 部件并覆盖 CreateChildControls(),然后在其中创建您的控件实例。如果您已经拥有控制权,那么使用 VWP 就没有用处了,因为 SharePoint 工具很可能会创建一些您不知道的绑定。

【讨论】:

这不是很有用。一般来说,ASP.NET 开发的核​​心原则之一是能够跨页面或其他用户控件重用用户控件。 当然可以。我只是说,如果您想使用可视 Web 部件而不是常规 Web 部件,您应该使用创建 VWP 时提供给您的控件。然后,您可以单独重复使用该控件,也可以将 Web 部件放置在任意数量的页面上。如果您想预先创建控件,请不要使用可视化 Web 部件;创建一个常规 webpart 并在 CreateChildControls() 中自己创建控件实例。 我不确定你是否理解这个问题。问题是我不能在 VWP 已经生成的 ASCX 中使用用户控件。我有一系列复杂的 web 部件需要制作,并且我有一组常见的用户控件应该在这些 web 部件中使用,但是现在 VS 的可怕的错误 Sharepoint Project 模板不允许我这样做。到目前为止,我可以想到几种解决方法,但目前没有一个是真正可取的。【参考方案2】:

在将引用标记写入 ascx 时,您是否尝试过在 VS 中使用浏览机会?它应该在输入 Src="

后出现

这应该确保引用是正确的。

此外,在代码隐藏中使用用户控件时,您需要将其转换为正确的类型才能访问您定义的属性,因为 VS 中的设计器文件将始终将其标识为用户控件.

【讨论】:

强制转换是我正在考虑的解决方法之一,但我试图远离,原因有两个:1)它可能导致一些混乱的代码,不得不在所有地方不必要地强制转换,和 2) .ASCX 文件中仍然没有智能感知。也许这个错误会在 VS11 中修复。 我确实在我的 ascx 文件中获得了智能感知。它认为这取决于 VS 是否可以解析 Src 参数中的引用。您是否按照我的建议尝试浏览到 ascx? 这很奇怪——有时我确实得到了智能感知,有时我没有,有时我得到的智能感知来自 .ascx 本身的几个小时前的版本。当我得到智能感知时,.designer 文件中的用户控件类型也得到了正确设置。我认为核心问题在于 GAC,但我无法通过部署、撤回或 Visual Studio 重启的任意组合来获得智能感知更新的一致行为。【参考方案3】:

您显示 MyWebPart.ascx 和 MyWebPart.ascx.cs。我想你也有 MyWebPart.cs。 此 MyWebPart.cs 加载 userControl MyWebPart.ascx。

你应该有这样的东西:

 private const string _ascxPath = @"~/_CONTROLTEMPLATES/YourPath/MyWebPart.ascx";

    protected override void CreateChildControls()
    
        Control control = Page.LoadControl(_ascxPath);
        Controls.Add(control);
    

如果要在可视化 Web 部件中添加另一个 userControl,则应获取 hive 下的标记并以与加载 MyWebPart.ascx 相同的方式加载它。

例子:

 private const string _ascxPath = @"~/_CONTROLTEMPLATES//YourPath/MyWebPart.ascx";
 private const string _ascxPath2 = @"~/_CONTROLTEMPLATES/YourPath/MyControl.ascx";

 protected override void CreateChildControls()
 
    Control control = Page.LoadControl(_ascxPath);
    Control control2 = Page.LoadControl(_ascxPath2);
    Controls.Add(control);
    Controls.Add(control2);
 

现在在您的 MyWebPart.ascx 上,假设您的 userControl MyControl 已部署到 GAC,之后 一个 iisreset 您应该以这种方式注册控件:

<%@ Register TagPrefix="MyTag" TagName="MyControl" Namespace="MyNamespace.Something" Assembly="MyAssembly.Something, version=1.0.0.0, Culture=neutral" %>

这样你应该有智能感知和访问你的属性

【讨论】:

以上是关于嵌套用户控件在可视 Web 部件中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Javascript 在 ASCX 中不起作用 – ASP NET 用户控件

创建加载用户控件的 SharePoint 2013 Web 部件

使用属性更改简单绑定到用户控件在 vs 扩展工具窗口中不起作用

jQuery ajax 在 Sharepoint 可视化 Web 部件中不起作用

在 Sharepoint 2013 中将用户控件添加到 Web 部件

脚本在 Web 浏览器控件中不起作用