Using Controls with MVP pattern

Posted by Community Admin on 03-Aug-2018 10:04

Using Controls with MVP pattern

All Replies

Posted by Community Admin on 23-Sep-2010 00:00

Hi,

we are using the MVP pattern with our usercontrols (.ascx).
The usercontrol is just a view which needs a presenter to control it.
Outside Sitefinity we initialize the presenter class in the hosting aspx page like this:

    protected void Page_Load(object sender, EventArgs e)
        InitCurrentTimeView();
   

    private void InitCurrentTimeView()
        CurrentTimePresenter presenter = new CurrentTimePresenter(currentTimeView);       
        presenter.InitView(IsPostBack);
   

In Sitefinity I just drag/drop a custom usecontrol in a page. How could I achieve the above initialization? We would not like to put this code inside the usercontrol itself.

Regards,

Martin

Posted by Community Admin on 23-Sep-2010 00:00

Hi SolarX,

Thank you for using our services.

First you need to add your user control in the website root. Lets say that you create a folder ~/UserControls/ and add your user control there. Then you will make sure that all of your dependent assemblies are located in the bin and build the the web application. You will register your user control in a toolbox section through the Sitefinity Configurations page and the control will appear in your toolbox. In the control type field you will enter the path to your user control. This should be sufficient to make your user controls work within Sitefinity and you would not have to change your initialize logic.

Regards,
Radoslav Georgiev
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 23-Sep-2010 00:00

Hi,

this I already know and understand.
My question is:

If I have my usercontrol all setup in Sitefinity and place it (from the SF-toolbox) in a SF-page, how can I run my initialization code within the SF-page?

Regards,

Martin

Posted by Community Admin on 23-Sep-2010 00:00

Hi SolarX,

I can see that you currently call your initialization logic on Page_Load event of the user control. This is still valid for Sitefinity pages as well. Here you have to decide if your control will be initialized when in design mode (while editing page for example) of if you want to initialize the control only if the page is being viewed on the public side:

using System;
using System.Web.UI;
 
namespace SitefinityWebApp
    public partial class WebUserControl1 : System.Web.UI.UserControl
    
        protected void Page_Load(object sender, EventArgs e)
        
            //determine if control is in design mode
            //if not call initialize logic
            if(!this.IsDesignMode())
                InitCurrentTimeView();
        
            ...
    


Best wishes,
Radoslav Georgiev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 23-Sep-2010 00:00

Hi,

thank you for your quick reply!

As I said in my first post. I call this code in the hosting aspx page and NOT in the usrcontrol.
Our usercontrols are not supposed to contain such code since they are supposed to be "dumm" views...wich is intergral to the MVP pattern.
So again: We do call the initialization code (as shown in my first post) in the page_load event of the page (.aspx) and not the usercontrol (.ascx).
What you suggest was pretty clear to me from the beginning, but is not what I want to achieve.
I do hope that there is a solution to that in SF, since we don't want to change the way we use the MVP pattern.

Regards,

Martin

Posted by Community Admin on 23-Sep-2010 00:00

Hi SolarX,

You can work with master pages in this case. You will create master pages which will serve as your page templates within Sitefinity. Then using the Sitefinity API on page load of the master page you can get the current Sitefinity page being viewed and check if this page contains a control of type which will be your user control. If so you will Initialize your presenter. Consider the sample code bellow:

protected void Page_Load(object sender, EventArgs e)
    //get your current page.
    SiteMapNode currentNode = SiteMapBase.GetCurrentProvider().CurrentNode;
    PageSiteNode node = (PageSiteNode)currentNode;
    var pageData = App.WorkWith().Pages().Where(p => p.UrlName == node.UrlName && p.Page.Status== Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Live).Get().First();
    //here you will have to use your control type if it is the user control the type will be its path
    var myControlData = pageData.Page.Controls.Where(c=>c.ObjectType == "CoverFlowWidget.CoverFlow").SingleOrDefault();
    //get an instance of the control on the page
    var pageManager = PageManager.GetManager();
    var controlInstance = pageManager.LoadControl(myControlData) as CoverFlowWidget.CoverFlow;


Best wishes,
Radoslav Georgiev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 16-May-2011 00:00

Martin,

Did you ever have any luck finding a way to implement the MVP pattern in controls built for Sitefinity?  I'm guessing that Radoslav's suggestion that the put control initialization code in the containing master page was not a solution you opted for...  Ever have any luck with it? 

I've been experimenting with the WebFormsMvp framework, but have found it doesn't play well with SF for similar reasons.

Thanks!
DanO

Posted by Community Admin on 17-May-2011 00:00

Hello Dan,

Can you please let us know a little bit more on what you are trying to achieve with WebFormsMvp framework and how you approach the problem? Please note that we have introduced an option to specify base page for your Sitefinity pages and all the initialization logic suggested previously can be moved from the master page to the base page.

Regards,
Radoslav Georgiev
the Telerik team

Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 17-May-2011 00:00

Radoslav,

I am trying to use WebFormsMVP with SF 3.7, and hit an error due to the fact that the control is loaded by Sitefinity so late in the page life cycle (PreRender).  Here's a thread I have going on the subject with the creator of WebFormsMVP:

http://groups.google.com/group/webformsmvp/browse_thread/thread/11a7f57f0ef9968

Can you point me in the direction of some documentation on how to specify my own base page in Sitefinity?  If I take that approach, is there a way to add controls to the page earlier in the event life cycle?  (I'm talking about controls added via the SF UI of course).

Thanks, DanO

Posted by Community Admin on 17-May-2011 00:00

Just realizing you attached a screen shot - however, that is not looking familiar - is that from SF 4+?  We're using 3.7 - is specifying your own base page not an option in 3.7?

Thanks, DanO

Posted by Community Admin on 18-May-2011 00:00

Hello Dan,

The forum thread is located in the Sitefinity 4.x forums, in your first message you did not specify which version you are using, so I gave you information about the current latest official release. In Sitefinity 3.x you have to inherit from InternalPage class and substitute the default type with your custom class in ~/Sitefinity/cmsentrypoint.aspx. Please note that in Sitefinity 3.x  controls are added to the page in CreateChildControls method.

Regards,
Radoslav Georgiev
the Telerik team

Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 18-May-2011 00:00

Radoslav,

So would it be possible to override InternalPage so that CreateChildControls gets called earlier in the life cycle (like in the Page Init event)?  I used Reflector to look at the source of InternalPage and it's base classes (CmsPageBase and RadAjaxPage), but I'm not seeing where CreateChildControls gets called.  Based on the trace.axd info, I would expect to find it in an OnPreRender method somewhere, but I don't see one in any of those classes.

If I add an OnInit in a class that inherits InternalPage, and call CreateChildControls there, won't I also have to override the method that is currently calling CreateChildControls?  If you could point me in the right direction or post some code, I would appreciate it.

Also - assuming this is all possible - do I have to worry about the change in timing screwing up any functionality in Sitefinity?

Thanks, Dan

Posted by Community Admin on 18-May-2011 00:00

I went ahead and created a new class to inherit from InternalPage and overrode the OnInit event, and that seems to work.  I was concerned that CreateChildControls would get called twice, but it doesn't seem to based on what I am seeing in the trace.axd.  Here's the code:

cmsentrypoint.aspx updated to:

<%@ Page Inherits="XXX.Web.UI.Sitefinity.cmsentrypoint" MasterPageFile="~/Sitefinity/Dummy.master" %>

added cmsentrypoint.aspx.cs:
namespace XXX.Web.UI.Sitefinity
  public partial class cmsentrypoint : Telerik.Cms.Web.InternalPage
  
    protected override void OnInit(EventArgs e)
    
      CreateChildControls();
      base.OnInit(e);
    
  

Radoslav - let me know if you think this customization could cause any issues in Sitefinity, or whether you think I need to override any other events in the life cycle.

Thanks, DanO

Posted by Community Admin on 18-May-2011 00:00

Radoslav,

While Dan is trying to get ASP.NET WebFormsMVP running in Sitefinity 3.7, I am trying to do the same in Sitefinity 4.1. My question is this: how do you specify a custom base page/code behind type in Sitefinity 4.1?

I did a Google Search and also searched using your site's search feature, but was unable to find the relevant information.

Thanks,
Troy

Posted by Community Admin on 18-May-2011 00:00

Troy,

Take a look a few posts up at the screenshot Radoslav attached.  There's a field in the advanced tab of the page editor that allows you to specify a base page.

-Dan

Posted by Community Admin on 18-May-2011 00:00

Dan,

For whatever reason, perhaps because I am using the trial version, I do not see the option in the advanced page properties as shown by Radoslav. (A screenshot of what I saw is attached.) I also checked the template upon which my test page is based, but did not see an option for specifying the page base class their either.

I really want this to work, as Sitefinity + ASP.NET Web Forms MVP may be the most appropriate architecture for my client, who would prefer to implement everything in ASP.NET MVC 3. The WebFormsMVP-based approach will at least facilitate a good separation of concerns, and I can reuse presentation and input models and other application code in a potential future MVC rewrite with this approach.

I have looked at Orchard, which I understand is based on ASP.NET MVC, but with the size of the site/project and the skillset of my team, I am uncomfortable with such a new and relatively unproven platform.

-Troy

Posted by Community Admin on 18-May-2011 00:00

Troy,

I don't have a version of 4+ running right now, but does it still use cmsentrypoint.aspx?  If so, maybe you could take the 3.7 approach, and create your own global base page override.  If not, I'm guessing Radoslav will be able to help you get that base page feature enabled.

Another option we are considering is implementing a simplified MVP pattern ourselves that eliminates all the event wireup (calling the presenter directly from the view), which to me seems like bolierplate code you will never test anyway.

I hear you regarding MVC - we really want to work in MVC, but there are not many good CMS options out there yet, which is an essential element for most of our projects.  Orchard is an interesting project, but seems overly complex.  I also don't like their extensive use of dynamic objects.  Sort of negates one of the great things about MVC - having views bound to models, with intellisense available in the view.  Anyway... I'm off topic for a post about MVP on the Sitefinity forum...

Good luck!
DanO

Posted by Community Admin on 08-Jun-2011 00:00

Dan,

Sitefinity 4.1 SP1 enables you to specify the base class to use for a given page. While this enables a developer to hack around a bit to try to get a UserControl built with WebFormsMVP to work, this feature will not work in the real world.

First, I cannot possibly expect my client to set a base class for every page in which they want to use the controls we build. Having to ask a marketing person to deal with this is unrealistic.

Second, the solution (which involves creating a class that inherits from SitefinityPage and adds a CreateChildControls() call to the Page_Init) only solves a runtime issue, not a design time issue. When I add my MVP-based widget from the toolbox to a page, I still get the "Model not initialized" error because the shiny new base class I specified for the page only seems to be used at run time, not design time. I have tried creating an empty model in both the Init and Load event handlers of my user control, but the problem is that the DesignMode property of the UserControl is set to false at design time, so I have no good way of knowing if my UserControl is being dragged into a placeholder at design time, or running in the page at run time.

-Troy

Posted by Community Admin on 08-Jun-2011 00:00

Troy,

Is there still a global cmsentrypoint.aspx in SF4?  If so, you could override all pages, and avoid the useability issue.  I was able to do that in SF3.7 and get WebFormsMVP working without a problem.

For what it's worth, we evaluated SF4 awhile back and decided it was not mature enough to adopt.  So we have continued using 3.7.  Similarly, after trying out WebFormsMVP a bit, we decided to implement the MVP pattern ourselves.  The version of the pattern we use is actually simpler and more straight forward to work with than WebFormsMVP, and there is no black box or compatibility issues.  If you are interested, I used the following book for guidance on implementing the MVP pattern:

http://www.wrox.com/WileyCDA/WroxTitle/Professional-ASP-NET-Design-Patterns.productCd-0470292784,descCd-DOWNLOAD.html

So far we're liking the approach quite a bit, and feel like it works well for custom user controls built for use in SF projects.

Good luck to you!
-Dan

Posted by Community Admin on 14-Jun-2011 00:00

Dan,

There is no CMSEntryPoint.aspx in Sitefinity 4.1 SP1. As far as I can tell, there is no universal way of specifying a base page in this version of the product. There is a way (as of SP1) to configure the base class of an individual Page through the admin interface, but that is problematic for a couple of reasons.

First, if I am building widgets using WebFormsMVP for a customer, I have an issue with requiring that customer (presumably non-developers) to remember to set the base class for every Sitefinity Page they create and to which they add these MVP-based widgets. Second, even if setting the base class for a Sitefinity Page works at run time, the Page design time experience doesn't use the base class, and the WebFormsMVP-based widgets throw errors when dragged into a content place holder.

I have actually gone forward and created an MVP-based approach that is partially tied to the WebFormsMVP library but that avoids the problematic ties to Page events. It does require that the Presenter get manually bound to the View in the constructor of the UserControl (or Page), but so far it seems to work OK. It also doesn't have many of the other nice features of WebFormsMVP (like the intra-component messaging, multi-view presenter and so on), but I am hoping I don't run across any requirements of my project that would make those necessary or beneficial.

-Troy

Posted by Community Admin on 14-Jun-2011 00:00

[Edited this response to delete the text since I accidentally added it to the thread twice. My actual response precedes this one.]

This thread is closed