2
votes

Despite my best efforts, I've been tasked by my employer to develop a web application using Sharepoint, instead of something useful.

I'm having trouble embedding User Controls into Visual Web Parts in a Sharepoint project in Visual Studio 2010. I'm using the following steps (note that this code is just a synopsis of what I have- as my real code currently contains enough curse words to get me banned from StackOverflow for life):

  1. Create a new, empty Sharepoint project.

  2. Add a User Control to the project (located in ControlTemplates), named 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";
    }
}
  1. Add a Visual Web Part to the project, MyWebPart.ascx

MyWebPart.ascx

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

When I get to this point, I don't get any intellisense for MyControl, more than likely because VS doesn't know of the existence of the .ascx file. I also get the green squiggly line under the control name letting me know it doesnt exist. However, I can still deploy the project to my Sharepoint server itself and all will work well.

However, this falls apart when I need to do anything useful interacting with the control itself:

MyWebPart.ascx.cs

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

Which yields an error of "System.Web.UI.UserControl does not contain a definition of 'Property' and no extension method...'. The designer.cs file indeed specifies the control as a UserControl, and not its real type.

Since this now yields a build error, I can't deploy the project to the Sharepoint server, so I can't really work around this intellisense issue.

I've found this to be very inconsistent behavior; sometimes the intellisense will appear, depending on whether or not the project is currently deployed to the server. However, there's not a predictable set of steps I've been able to take to get the development environment in a working state.

Any thoughts? Things I've tried:

  1. Right clicking on the web part's ASCX and clicking "Open With..." and choosing the "With Encoding" option. No effect.

  2. Developing with the application both deployed and retracted, and various combinations of closing and reopening the .ascx files, the solution, and Visual Studio itself. Sometimes works, sometimes doesn't.

  3. Disabled the project's "Auto-Retract after Debugging" option (recommended from a knowledge base article). No effect.

3
Have you got the solution? I am stuck on the same page.Rishi Jagati

3 Answers

1
votes

When creating a visual webpart you get the control "for free". Create a VWP and stick your stuff into that control instead of creating one beforehand.

If you want to use the control you've already created, create a regular webpart and override CreateChildControls(), and create your control instance in there. No use mucking around with VWPs if you already have the control, as the SharePoint tools most likely creates a few bindings you don't know about.

1
votes

Have you tried using the browse-opportunity in VS when you are writing the reference tag to your ascx? It should appear just after typing in Src="

That should ensure that the reference is correct.

Also, when working with the usercontrol in your code-behind, you need to cast it to it's proper type to be able to access the properties you have defined, as the designer file in VS will always just identify it as a UserControl.

1
votes

You show MyWebPart.ascx and MyWebPart.ascx.cs. I suppose you also have MyWebPart.cs. This MyWebPart.cs load the userControl MyWebPart.ascx.

You should have something like this:

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

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

If you want to add another userControl in the visual web part, you should take the markup under the hive and load it the same way MyWebPart.ascx is loaded.

Example:

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

Now on your MyWebPart.ascx, assuming that your userControl MyControl is deployed to GAC, after one iisreset you should register the control this way:

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

This way you should have intellisense and access to your properties