MvcContrib - How to get Area into MenuBuilder ActionLink - asp.net

I am using MenuBuilder with code like this:
public static MenuItem MainMenu(UrlHelper url)
{
Menu.DefaultIconDirectory = url.Content("~/Public/Images/");
Menu.DefaultDisabledClass = "disabled";
Menu.DefaultSelectedClass = "current";
return Menu.Begin(
Menu.Items("",
Menu.Action<HomeController>(p => p.Index(), "Home")
),
Menu.Items("",
Menu.Secure<HomeController>(p => p.About(), "About")
),
Menu.Items("",
Menu.Action<RegulationController>(p => p.Index(null), "Compliance")
)/* This is in the Compliance area */
).SetListClass("menu");
}
But I am also using MvcContib Areas and in the code above the final menu item is in an 'Area' called 'Compliance'.
(There are two other areas in the Mvc application and the first in the list of registered areas is called 'Legislation')
What happens is the following:
When a page is rendered (I am using the standard WebFormsViewEngine) the Urls are all rendered using the 'Legislation' area!!?
E.g. http://localhost:1337/Legislation/Home or http://localhost:1337/Legislation/Home/About
and finally http://localhost:1337/Legislation/Regulation
The first two links should not pick up the 'Legislation' area. The last menu item should be in the 'Compliance' area.
How do I prevent the erroneous Area (Legislation) being rendered on the first two links?
How do I get the MenuBuilder markup in the Site.Master to accept an 'area' attribute or get it picked up automatically from the Controller for each link?

It seems that MvcContrib MenuBuilder does not play well with Areas. In the end I took the Areas out and the problem went away.
However, I recognise there may have been some other issue in the Mvc application which may indeed have been related to the older (beta?) version of Mvc dll that MvcContrib was referencing.
So for anyone that comes across this it may indeed be a none issue.

Related

Storing a view in Xamarin.Forms MvvmCross

I have an app with four main pages, switched through a tab bar (no "back" button).
One page has a lot of content (ScrollView) and takes quite a few seconds until it's rendered. I handle that by showing a "loading" overlay while the work is done. But for that specific page I'd like to keep the view alive, so that when the user switches to another page and comes back later, the page is ready without loading everything again.
I'm not sure how to do that in MvvmCross, though.
I did read the documentation and from what I understood the View Presenter would be the right way to do it, since the docs say:
"Another kind of presentation changes your app can request through
hints includes clearing / modifying the BackStack, changing a root
while maintaining the existent views, … possibilities are really
endless. Once again your app is king here!"
I guess I would need to create a custom MvxPresentationHint for that, but I don't quite get it :(
How or rather where would I access and store/load the View?
I'm generally still quite unfamiliar with MvvmCross (how it works under the hood) and especially customization of Mvx classes, even though I've been using it for a while.
Any explanation and preferably code examples beyond what's written in the documentation would be extremely appreciated!
It isn't meaningful to attempt to "store" a view in MVVM. The XF view is a representation of what will be created with native (e.g. "Android" or "iOS") widgets. Creating and measuring/laying out those native widgets is what is slow. MVVM View Presenter won't speed up that logic.
Instead of "store", you need "keep alive":
For a ContentPage called MyPage, when you create it, store it in a static variable. Then re-use that variable. If you never need more than one of these, you can store it in the class itself.
Modify the "code behind", MyPage.xaml.cs:
public partial class MyPage : ContentPage
{
// Singleton Pattern.
private static MyPage _it;
public static MyPage It {
get {
if (_it == null)
_it = new MyPage();
return _it;
}
}
// "private", because calling this directly defeats the purpose. Instead, use `MyPage.It`.
private MyPage()
{
InitializeComponent();
}
}
To create it, whereever you would put:
new MyPage()
instead put this:
MyPage.It
For instance, you might do PushAsync(MyPage.It);
This will always return the SAME INSTANCE of MyPage. So once it has been created, it keeps its state.
IMPORTANT: Note that the constructor is only called ONCE. Any code that needs to be done each time the page appears, put in override .. OnAppearing() method.
LIMITATION: Views "expect" to be part of the visual hierarchy when they are manipulated. If you attempt to alter the page or its view model while it is not on the screen, you may encounter problems. Those are beyond the scope of this answer - create a new StackOverflow question with the details of any problem you encounter.

Default.ctp and a totally different login page

Within my default.ctp page I keep navigational and structural content applicable to the entire application. For example menu structures and a column based CSS. I would like to change my login page, however, to look entirely different (no menu, no columns, etc)
Is there a way to load a separate ctp file for a single URL only? e.g. /plugin/controller/login
http://book.cakephp.org/2.0/en/views.html
You can create a new layout for the login page and for that controller/action change the layout name
$this->layout = 'login';
There are two ways. First, you create your new layout file, à la login.ctp inside your View/Layout folder.
Next, in your login action, at the top you can write $this->layout = "login";. The other way you can do it is when you render the view, at the end of your action method, like this: $this->render('actionName', 'login');

How navigate to next page using AJAX in MVC4?

I don't have so much experience using AJAX in a MVC application, in fact is my first facing. Please check the below image and note the rectangles.
The image is just an example that I took from internet.
The biggest rectangle is a partial view in my application and I have to render it when the user press Continue or Continuar button. The application should replace the current view for another without refresh the page.
This is the code which I'm testing, note first that I'm passing the first element of a list, but when the user press the button, render the view with the next element index = 2.
public ActionResult DoTest()
{
if (!Request.IsAjaxRequest())
{ }
List<Worksheet> worksheets = new List<Worksheet>()
{
new Worksheet("Hoja 1", ...),
new Worksheet("Hoja 2", ...)
};
return View(worksheets[0]);
}
Can orient me a little bit to know how to implement this feature? I just know that I need to use Ajax.
Have a look through the tutorials and examples here. There's plenty of other material around on the web with information on this subject.
There are many different ways you can achieve this. One way would be to write a custom paging Helper (HtmlHelper) that accepts new content upon the post event. You can view all about Helpers here : Custom HTML Helpers
Another way could be to use partial page rendering to achieve the partial page update upon post event.
If I was you I would combine a partial view with a jquery function to update the content. You can view some help on that here: Change dive content with Jquery

sharepoint 2010 cannot get global navigation nodes in code

I have sharepoint site and i want read in code global navigation information.
On properties page:
/_layouts/AreaNavigationSettings.aspx
I added "location","organization","98" nodes.
But when i am trying to get those nodes in code
using (var site = new Microsoft.SharePoint.SPSite(URL))
{
using (var currentWeb = site.OpenWeb())
{
return currentWeb.Navigation.GlobalNodes;
}
}
I have always those nodes:
Home
Quick launch
SharePoint Top Navbar
Why i have those strange nodes and how to get real globan naviigation/?
SharePoint's navigation is hierarchical. The hierarchy has exactly three nodes:
Home — represents the single 'home' icon in the upper left;
Quick launch — represents the quick launch menu at the left side of the page;
Top navigation bar — represents the navigation bar at the top of the page.
You have to delve into subnodes of these node to find your three nodes — see the SPNavigationNode.Children property. SharePoint lacks unique identifiers for navigation nodes so you have to rely on titles (display names).
UPDATE: Also please note that your code contains a serious design flaw. You are returning an object that's logically nested within a SPWeb out of the scope where the SPWeb instance is alive—i.e. out of the using statement. While this may work for navigation nodes generally such behavior will lead to errors. Those errors are often handled internally by SharePoint and result 'only' in logged error messages, but that's definitelly what your code should produce.
This works for me:
var pubWeb = PublishingWeb.GetPublishingWeb(web);
foreach (SPNavigationNode navigationNode in pubWeb.Navigation.GlobalNavigationNodes)
{
//do stuff
}

Masterpage -> SubMasterPage -> Web Form...getting properties of Masterpage in sub pages

I asked a related question on this yesterday, and was told what not to do, but not what I should do.
I've got a master page that I'll call "TheMaster". I've got 2 sub master pages "Sub1" and "Sub2". They both have a Masterpage directive of "TheMaster". Web Forms have a Masterpage directive of "Sub1" or "Sub2". These aren't the real names.
In "TheMaster", I figure out what page the user is on, find out where in the Web.sitemap they are, and using that, I have the Web.sitemap node and the parent and the parent's parent, if they all exist. I use this to build navigation dynamically and highlight the current page.
Now, our designers have several places this navigation appears. Top nav, sub nav, teritiary nav on the left, and a "breadcrumb" style showing home -> parentparentnode -> parentnode -> currentpage
I can NOT define all of this in "TheMaster" due to layout constraints.
So, in "TheMaster", I find their current node, and save that as a public property of "TheMaster" (along with several other pieces of info.
In Sub1, even though it is using "TheMaster" as it's masterpage, it does not appear to be able to find my public properties from "TheMaster".
Any ideas on how I can get this info to be available all the way through this house of cards?
I've tried
Page.Master.myProp (nope)
Parent.myProp (nope)
I can't think of anyything else to get this to work. "TheMaster" has basically no knowledge of "Sub1", so I can't set a property on Sub1 and have it go down the tree, and the nodes down the tree are apparently oblivious to their parents...???
Cast Parent or Page.Master to your actual MasterPage class.
((MyMaster)Page.Master).myProp // found!
Casting gets you there, but it isn't so clean nor maintainable in the long run. I've done very, very complex versions of this using a series of interfaces to abstract things. See this blog post for a simplified version with one layer. The trick to adding more layers is just adding some more interfaces and abstract classes as appropriate.

Resources