DotNetNuke DDRMenu set NodeSelector in code behind - c#

I'm using DDRMenu in DotNetNuke to select a menu node from my site structure and display only a subnode in a specific navigation in my template
<%# Register TagPrefix="dnn" TagName="MENU" Src="~/DesktopModules/DDRMenu/Menu.ascx" %>
<dnn:MENU ID="MenuFooter" MenuStyle="MenuFooter" IncludeHidden="true" NodeSelector="FooterNavigation,0,1" runat="server" ></dnn:MENU>
Now I want to be able to set the NodeSelector attribute in the code behind file, because I want to be able to dynamically set the value on Page_Load
// load footer navigation node from a config file
protected void Page_Load(object sender, EventArgs e)
{
var footerNode = Config.Instance.Navigation.FooterNode;
MenuFooter.NodeSelector = footerNode + ",0,1";
}
But this doesn't work, as there is no NodeSelector attribute on System.Web.UI.UserControl.
Error 'System.Web.UI.UserControl' does not contain a definition for 'NodeSelector' and no extension method 'NodeSelector' accepting a first argument of type 'System.Web.UI.UserControl' could be found (are you missing a using directive or an assembly reference?) C:\Projects\eWolf2012\dev\DNN\Portals_default\Skins\JWEwolfSkin2012\Simple.ascx.cs 141 24 JWEwolfSkin2012
Is there any way to achieve this?
Kind regards

Usually the Menu.ascx in DDRMenu inherits from the DDRMenu SkinObject:
<%# Control Language="C#" AutoEventWireup="false" EnableViewState="false" Inherits="DotNetNuke.Web.DDRMenu.SkinObject" %>
Since you are talking about changing the code behind I guess that you are using a custom control that embeds the Menu.ascx. In which case you should be able to access the NodeSelector property since it exists in the SkinObject class.
What I am suspecting is happening is that your control type is not loaded correctly by the designer, and that it falls back on the UserControl type which doesn't have the NodeSelector property.
Try the following:
Include the DDRMenu assembly in your current project (because it won't load the type if it doesn't find the assembly), then rewrite the include to kick the designer into motion. I'm pretty confident this is the cause of the problem, but if not:
Fiddle with your src attribute and check in the *.designer file what type is defined.
Define it manually in your code-behind file instead of letting the designer do it.

Related

I need help identifying a programming technique so that I can research and fix it

The Code:
ParentControl.ascx
<%# Control Language="C#" AutoEventWireup="true" CodeFile="ParentControl.ascx.cs"
Inherits="ParentControl" %>
<%# Register Src="~/ChildControl.ascx" TagPrefix="Prefix" TagName="ChildControlTag" %>
ParentControl.ascx.cs
public partial class ParentControl : UserControl
{
List<ASP.childcontrol_asxc> controlList = new List<ASP.childcontrol_asxc>();
... inside a public property setter ...
var control = new ASP.childcontrol_ascx(); // <ABC> what the heck is this reference?
controlList.Add(control);
...
}
ChildControl.ascx
<%# Control Language="C#" AutoEventWireup="true" CodeFile="ChildControl.ascx.cs"
Inherits="ChildControl" %>
<asp:Repeater ID="childRepeater" runat="server" EnableViewState="false"
ViewStateMode="Disabled">
ChildControl.ascx.cs
public partial class ChildControl : UserControl
{
...
protected void Page_Load(object sender, EventArgs e)
{
childRepeater.DataSource = xyz; // <XYZ> crashes if I don't use the weird reference
}
}
The Problem:
I don't understand what the reference comment marked with <ABC> is all about. That's not the class I defined... but Intellisense doesn't complain. If I press F12 on it, it takes me to the <%# Control ... %> tag at the top of ChildControl.ascx instead of the control definition in ChildControl.ascx.cs.
I don't understand what this other version of the control is, why it's in the ASP namespace, or what the implications of using it instead of the control directly are. Worse, this compiles fine on my local workstation, but throws a compiler error on the TFS server we use for CI.
The Question:
Does anyone know the name for this method of using/referencing the custom User Controls, and/or have links/information I can look at to get a better handle on what this is and what the implications are? I've been unable to find anything useful via Google. While a fix/workaround would be great to have - I would still like to be able to research the technique.
Explorations:
I've tried replacing the usages with the actual class name, instead of the weird ASP.class_ascx references... it compiles fine if I do this, but unfortunately it fails at runtime. It seems like the other reference changes how it interacts with the asp.NET lifecycle - server controls defined in the aspx of the child control are null in the Page_Load() of the child control (marked <XYZ>). Under the weird ASP.control_ascx reference approach, the repeaters are properly defined when it hits the Page_Load() of the child controls, but I don't understand why.
Miscellaneous:
The project is using the Roslyn compiler on my local workstation, via the DotNetCompilerPlatform NuGet package but I believe its just using the VS/TFS 2015 built in compiler on the CI server. This might explain why TFS throws compiler errors - it tells me The type or namespace name 'usercontrol_ascx' does not exist in the namespace 'ASP' (are you missing an assembly reference?). I'm looking at configuring TFS to use the compiler from the NuGet package which will then hopefully compile - but this is still weird and I'd like to understand it.
This is the class that the ASPX file compiles to. It inherits your class and adds code that renders your ASPX content.

Using html <a> tag instead of LinkButton, can't access c# code-behind

I'm tryna create an ASP.NET Empty Web application that allows users to sign up and log in to access different pages from the public. I'm currently using a masterpage that holds the navigational links, using the html tag. However, for one of my buttons it is used to Sign Out of the user's account to redirect them back to the page where the public that isn't logged in are able to access. However, to use a code behind, it'll probably require me to use a LinkButton to access the c# code behind for my sign out code, which is
FormsAuthentication.SignOut();
Response.Redirect("Index.aspx");
However, if I use a LinkButton it is required for me to use a tag, which screws up my page layout (the navigational links). Is there a way I can use the tag and still access my c# code behind to implement the codes I've pasted above?
Anyway I tried this
<a id="signOutBtn" onclick="signOut_Click" onserverclick="signOut_Click" runat="server">Sign Out</a>
but I got this error:
Compiler Error Message: CS1061: 'ASP.masterpageuser_master' does not contain a definition for 'signOut_Click' and no extension method 'signOut_Click' accepting a first argument of type 'ASP.masterpageuser_master' could be found (are you missing a using directive or an assembly reference?)
Try runat="server":
<a runat="server" id="signOutBtn" onserverclick="signOut_Click">Sign Out</a>
And in your code behind, define your function:
public void signOut_Click(object sender, EventArgs e)
{
FormsAuthentication.SignOut();
Response.Redirect("Index.aspx");
}

Single ASPX page - No code behind - Page Directive

I have a single aspx page with no code behind with a directive like the following below.
<%# page title="Test" language="C#" masterpagefile="Test.master"
autoeventwireup="true" inherits="TestScenario, TestScenario2" %>
Where do I need to look for the code (in VS)for the info that the Inherits attibute is pointing to.
Which page does the inherirtance refer to so that I can physically go look at what the page does.
This is a follow up to my previous question https://stackoverflow.com/questions/14278082/no-code-behind-aspx-page-page-directive.
Any info or few sentences on how a single page (with no code behind) is tied to the inherit attribute in the Page directive is much appreciated.
TestScenario, TestScenario2 is an assembly qualified type name.
Look for a class called TestScenario in a project that creates an assembly called TestScenario2. If you're lucky, the file will be at TestScenario2\TestScenario.cs, relative to your solution folder.
In Visual Studio, go to a .cs file and type TestScenario OR TestScenario2. Right click on the TestScenario OR TestScenario2 you typed and click on 'Go To Definition'. You can see where those classes are defined.
But in normal case when an ASP page is added with no .cs file, you can add a .cs file by placing the CodeFile="~/Path" in the Page directive.
Hope it helps.

designer.cs issues with using user control in Visual Studio

During my development, I have a web user control project and another web project which will use the user controls from the web user control project.
So I copy the DocControl.ascx file to my web project and try to use the properties of the DocControl.ascx.
But VS does not know the properties of the control. So when I check the designer.cs, the reference is like that
protected global::System.Web.UI.UserControl Control;
Which should be
protected global::MSN.DocControl Control;
So I changed the name of the control from System.Web.UI.UserControl to MSN.DocControl and I can use the properties of the DocControl.ascx.
But my issue is whenever I modify ( eg. put a lable in aspx) the aspx file, the reference in designer.cs become
protected global::System.Web.UI.UserControl Control;
So I has to change it whenever I modify my aspx.
What should I do so I don't need to change the designer.cs
Thanks in advance......
I have solved it by moving
protected global::MSN.DocControl Control;
from designer.cs to .cs page.
So whenever you made any changes, it will be OK.
#kokbira - > hope that it helps you.
In my case, it was a bad src path in my register line. This caused no error messages, but would generate the generic control instead of the specific class, with the same symptoms you describe.
I had this (which has the wrong Src path):
<%# Register TagPrefix="uc" TagName="Pipes" Src="/Controls/Pipes.ascx" %>
...
<uc:Pipes id="ucPipes" runat="server" />
and it generated this, which is generic, and has none of the control's properties:
protected global::System.Web.UI.UserControl ucPipes;
When I did the correct path, with Category folder, it worked:
<%# Register TagPrefix="uc" TagName="Pipes" Src="/Category/Controls/Pipes.ascx" %>
...
<uc:Pipes id="ucPipes" runat="server" />
and generated this correct one, so all properties worked:
protected global::Company.Category.Controls.Pipes ucPipes;

C# Button Click

I have the following button on a .aspx page:
<asp:Button runat="server" ID="bntLogin" OnClick="bntLogin_Click" Text="Login" />
With the following in the .aspx.cs:
protected void bntLogin_Click(object sender, EventArgs e)
{
//
}
When I try to build it I get the following error:
'ASP.reserve_aspx' does not contain a definition for 'bntLogin_Click' and no extension method 'bntLogin_Click' accepting a first argument of type 'ASP.reserve_aspx' could be found (are you missing a using directive or an assembly reference?)
However, when I move the click event from the code-behind to a script block inside the markup it builds.
Any ideas?
Are you sure that you placed the method in the correct code-behind file?
Check which file you are using as your code-behind file by looking at the #page directive at the top of the aspx file itself (check the inherits attribute) - you may be surprised.
A loosely-related side note: By setting the OnClick with a string value that corresponds to the method you wish to invoke you are implicitly relying on ASP.NET's AutoEventWireup feature which I don't consider to be a good approach. It is better to manually wire up your controls in your page's OnInit override method like this:
bntLogin.Click += bntLogin_Click;
By relying on AutoEventWireup you are allowing the ASP.NET runtime to create this code for you and since this happens at execution time you are incurring an execution time performance penalty as well as risking an exception like the one you are seeing now.
I usually hook up the events in the code-behind's OnInit method, which is a hold-over from ASP.NET 1.1 (that's where the designer would put it back then.)
If by any chance you're still running ASP.NET 1.1, delete the aspnet_client folder, rebuild and try again.

Categories