Strange behavior of Control.Page in nested ViewUserControl - c#

I have a ASP.Net MVC view which contains other partial views derived of ViewUserControl. The view itself is contained in a master page, so the control hierarchy can be summarized as follows:
Master page - basic settings
ViewPage - "the" page
ViewUserControl - content component 1
ViewUserControl - content component 2
...
ViewUserControl - content component n
Additionally, we have a custom control for the declaration of CSS and Javascript files. This custom control ensures that, no matter how deep into the hierarchy, whenever there is a CSS or JS dependency it will be rendered inside the Page.Header, thus avoiding scattered and duplicated references. Let's call this custom control <my:dependency>.
All is well when <my:dependency> is hosted in the master or ViewPage. But if I use it deeper inside the content components, Page.Header is null. Debugging revealed that, for controls hosted in a ViewUserControl, their Page is the very ViewUserControl in which they're in, and so the Header is indeed missing.
How can I make <my:dependency> "see" the topmost ViewPage and get access to the Header? Thanks.

Now I could be wrong, but you appear to be trying to get a web forms control to work in MVC, something that is not recommended for reasons you've discovered.
You might want to look at something involving the ViewData collection.
Simon

Related

Referencing partial view or another master page inside dotvvm masterpage

I am trying to render something like razor's render partial in dotvvm master page. but found nothing from the documentation but the following:
Master Page Nesting
You can also nest a master page in another master page and so on. Just use the #masterPage directive in the master page to specify parent master page.
Basically I want to render navigation menu which will be defined in another master page in my parent master page.
I think that you are looking for a Markup Control, see the docs for more details: https://www.dotvvm.com/docs/tutorials/control-development-markup-only-controls/2.0
In short, markup control allows you to declare custom control in a dothtml file. You can use all DotVVM features in the markup control, you'll just have to explicitly declare how data from the view model should be passed if you want to use data bindings.
A minimalist markup control may look like this:
<!-- The control must be used when data context is this view model: -->
#viewModel Full.Name.Of.MyViewModelBase
<ul class=menu>
<li>{{value: NameOfSomething}}</li>
<li>...</li>
</ul>
Then, the control must be registered, so DotVVM can find it:
// in DotvvmStartup
config.Markup.AddMarkupControl(tagPrefix: "cc", tagName: "MyMenu", "Views/MyMenu.dotcontrol");
After that, you can use the control anywhere you want (well, recursion works only sometimes 😃):
<cc:MyMenu />
You can also declare properties and then use it inside the control. It may help with reusability of the control since the view model does not have to fit. I'll leave it to the docs

Deep linking/Navigating to tabbed page in prism not working

I have a master detail page as the root page for my application. As a detail page for that I have a tabbed page. In the tabbed page I have a content page and a navigation page containing one content page. In the master detail's OnNavigatedTo I'm retrieving some organisation data from the cloud and then I want to navigate to a manage organisation page which is the plain content page in the tabbed page.
Using NavigateAsync and a relative uri to the manage organisation page I find that the Tabbed Page OnNavigatedTo is hit twice and then I get an exception such as (simplified) below. I can also see Binding errors in my output showing that elements on my manage organisation page xaml tried to bind to the tabbed page view model.
I'm not sure if this is an issue with the view model auto wire change in 6.2 or if it's a deep linking issue or if I've done something wrong.
"Sequence contains no elements".
at System.Linq.Enumerable.Last[TSource] (IEnumerable`1 source) [0x00079]
at Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer.OnAttachedToWindow () [0x00011]
in C:\BuildAgent\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\AppCompat\NavigationPageRenderer.cs:189
Using XF 2.3.1.114, Prism.Forms 6.2, I'm not sure if other packages are relevant. If you think so I can include them.
Also interestingly, it works if I try navigate to the content page in the navigation page from the master detail i.e. "TabbedPage/NavigationPage/ContentPage".
Any ideas what the problem might be?
So first thing first, you don't have the proper XAML syntax for your TabbedPage. When defining the default page for a NavigationPage in XAML you must supply the page via the Arguments element:
<views:SimpleNavPage Title="Foo">
<x:Arguments>
<views:NestedContentPage />
</x:Arguments>
</views:SimpleNavPage>
You must also have the proper ctor in your navigation page:
public SimpleNavPage(Page root) : base (root)
{
InitializeComponent();
}
Now, I personally don't recommend navigating within the OnNavigatedTo unless you can absolutely guarantee that you will not be adding that page in another deep link, or navigation scenario. Imagine you start out with NavigateAsync("MainPage") and that has an OnNavigatedTo that does a deep link navigation operation. Now you decide to NavigateAsync("SomeOtherPage") in which it NavigateAsyc("AnotherPage/MainPage/SomeOtherPage/LastPage") from within it's OnNavigatedTo. Now, you will have created an issue because the MainPage.OnNavigatedTO will have kicked off another navigation operation while you are still navigating to the next "SomeOtherPage". You are asking for trouble.

How to access controls on a master page dynamically from another user control, if the web application has nested master page

I have a user control, say control 1, that looks for control2, which is placed on the root master page : Site.Master
And this is how I am getting Control2 from Control 1 now,
MasterPage showMaster = this.Page.Master.Master;
MasterPage siteMaster = showMaster.Master;
Control2= siteMaster.FindControl("Control2");
The above code works fine. But because our application uses nested master pages, I am running into a bit of situation here.
How do I find control 2 dynamically regardless of where I put Control1 in which template? Becasue right now, depends on where I put Control1, and how nested is that template in relation to the Site.Master, I have to change how far up in the chain I get Site.Master in the Control 1 code.
Any good ideas on how I can avoid doing that?
Please advise.
i found a work around with recursively loading the control

how to get the code file of another aspx page attached to my aspx page

My problem is to make a code behind file of an aspx i.e already existing 1.aspx pages aspx.cs
to be available to another page aspx with out replicating any of the code in code behind.
i.e 1.aspx --> code file is 1.aspx.cs.
now 2.aspx --> code file is 1.aspx.cs
under the condition that the controls used in both aspx pages have identical Ids
Honestly, if you have such requirement, you should better encapsulate common behavior either in a base class that can be inherited by the two page's dedicated class, or create utility/business class that contains the code.
You should also consider using User Controls. This can help you to create reusable visual component in your application.

Can I populate a ContentPlaceHolder in a master page from within a Razor Partial View?

I'm using the typical built in view engine in mvc3 (is there a proper name for it?) for views and master pages and it's including a Razor partial view on the .aspx page. In the masterpage, there is a ContentPlaceHolder with an ID of "ScriptContent".
I want to be able to fill that ContentPlaceHolder from within the Razor partial view but I don't think this is possible. Does anyone know if it is possible and how I would go about doing that?
I already tried rendering it in the partial like so, but that didn't work.
#section ScriptContent {
... content ...
}
It would be very difficult, so much so that I'd recommend finding another way :(. I wish it was easier, but these are the complexities of integrating a new view engine into an existing legacy system.
To give you a head start if you really want to try it: You'd probably need to create a custom base class inheriting from WebViewPage for your Razor content pages, override some of the methods (honestly I'm not too familiar with that aspect so you'd need to debug to follow the pipeline) so that instead of treating the Layout property as the path to a Layout page, you treat it as a Master page. Then you'd need to instantiate the master page and somehow convert the Sections (which were transformed into calls to DefineSection by the Razor parser, and should be stored in a Dictionary somewhere on the base class) in to Content controls and stuff them in the Master Page.
If I haven't boggled your mind by this point, you may just be able to pull this off, but to be honest, I'd avoid it.
P.S. We refer to the older view engine as "ASPX", based on its file extension ;).

Categories

Resources