I have a Pivot on MainPage.xaml; how can I call this from another class?
MainPage.mypivot.Items.Add(p);
Error 2 An object reference is required for the non-static field, method,
or property '...MainPage.mypivot' H:\Users\Lacroix\documents\...
You can't do that exactly because of the reason the compiler tells you. MainPage is not a static class, when you view the page an instance of the class is being displayed, so you need to manipulate that instance. What you can do is pass a reference to the MainPage class to the other class. Then have MainPage contain an instance of the other class.
In MainPage.xaml.cs
public partial class MainPage : PhoneApplicationPage
{
private MyClass _myClass;
MainPage()
{
_myClass = new MyClass( this );
}
}
Now, MyClass will have access to the Pivot (and all other elements of MainPage).
If whatever logic the other class uses to add items to the Pivot is not available when displaying MainPage, i.e. you need to add items when displaying some other page, you'll need to create a static list (say PivotItemsList) in the App class. Have the other class add items to this list instead of directly to the Pivot. You can then access this within the MainPage constructor as App.PivotItemsList and add the items to the Pivot.
Related
Im using Spring mvc 3.1 version and Apache Tiles 2.2.2 version i'd like to define some common modules in my applications pages.
For example i want to define a menu in the top, a left side and right side,.. all my page will display these block.
Im using Tiles to define the differents blocks, some part of tiles implements ViewPreparer because i need to get information from database, know if the user is logged,... each tile is responsable of its own module(get data, set attribute for the jsp...).
Is it a good way to create some modules ? Or should i define a controller who will define the data, the business...to all page modules ? (left side, right side, menu...)
If your common module only consists of HTML then it doesn't matter how you do it. Tiles template is sufficient.
The problem is if the common module need models to be populated on the controller. You don't want to duplicate the code on every single of your controller which view includes the common module.
One approach you can take is subclass your controller with a class that populates common module model, eg:
public class CommonHandler {
#ModelAttribute("loggedInUser")
public UserInfo getLoggedInUser() {
// check and return logged in user if any here..
}
}
#Controller
public class MyController extends CommonHandler (
#RequestMapping(..)
public String myHandler() {
// ...
}
}
In above example if myHandler is requested, getLoggedInUser from CommonHandler class will automatically be called to populate loggedInUser model. In your view you just obtain it using ${loggedInUser}
When using ViewPreparerSupport which implements ViewPreparer, it works very well :
#Component
public class MyPreparer extends ViewPreparerSupport {
#Autowired
private UtilisateurService utilisateurService;
#Override
public void execute(TilesRequestContext tilesContext,
AttributeContext attributeContext) {
//information to set for the jsp tile
}
}
How to display a default page like Maintenance page for all the views if a web.config key is set to true?
If the key is false, then show the regular views.
Plz note, I don't want to repeat the code in each controller and am looking for a common place, like _ViewStart or _Layout page where this can be defined.
Thanks.
You could create your own ActionFilterAttribute and base Controller, which gives you access to OnActionExecuting. You could then test if the Web.Config value is set (perhaps loading it into an Application variable when you first start your Web app) and if it is set, setting the Controller and Action attributes to your maintenance page. Then all of your controllers, instead of inheriting from the standard Controller would inherit from your controller instead, except for the Maintenance controller which could still inherit from the normal Controller.
For instance:
[RedirectToMaintenancePage]
public class MyController : Controller
{
}
And for a typical controller:
public class SampleController : MyController
{
... Your actions ...
}
Then create a class called RedirectToMaintenancePageAttribute.cs:
public class RedirectToMaintenancePageAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
If Web.config says to go to Maintenance page then...
{
filterContext.Result = RedirectToRouteResult("route name") // Or some other redirect
return;
}
// else
base.OnActionExecuting(filterContext);
}
}
This is all off the top of my head, but I think it should work, and if it doesn't hopefully it'll give you some ideas.
When a view model is created you can populate the options (e.g. used in a dropdown list) into a setter property of the view model.
The problem is that when that view model is later passed as a parameter (by the framework!) into an action method, those property values has not become automagically
repopulated, so if you need to redisplay the form because of validation errors, you need to repopulate those options again.
One potential solution, which I am asking for specifically in this question, is how to make the MVC framework instantiate the view model with constructor injection, which would provide the view model constructor with an implementation of some kind of data access object (e.g. a repository) that can be used for retrieving the options when they are requested by the view (e.g. in the helper method "DropDownListFor") ?
I think the solution might have something to do with implementations of IModelBinderProvider or IModelBinder but after having experimented with these things from example code snippets here and there on the net, I am still looking for a completely working example, with downloadable executable code without any missing piece of how putting all things together.
If you are looking for some alternative discussion about how to populate a select list, e.g. with "Dependecy Lookup" instead of "Dependecy Injection" you may want to check out the following discussion:
Best way to populate SelectList for ViewModel on GET/POST
Best way to populate SelectList for ViewModel on GET/POST
Some days ago I wrote the following follow-up-question in that thread about the "Dependecy Injection" I am now looking for in this thread:
https://stackoverflow.com/a/8674525/310457
(which provides a code example about the problem I am looking for a solution of)
But instead of hoping that someone will find that old thread with a less specific title, I have created this new question with a more specific subject about what I am looking for.
And I will also provide a link from that thread into this new question for anyone that want to follow-up regarding this specific solution I am looking for.
I'm assuming you want to have your ViewModels automatically injected with something via their Constructor - for example some kind of configuration object that the View will use to determine what to show. I'm also assuming that this approach is causing a "No parameterless constructor defined for this object" error when MVC tries to automatically create and bind a model instance, from the arguments of your Controller Action. Let's also then assume that we will use a DI framework to inject the SiteConfig object into our Controllers automatically at runtime.
This means that the only problem we have to solve is how to get the injected object from our Controller into its Actions' ViewModels when they are automatically bound.
So let's define a base model for others to inherit from.
BaseViewModel
public class BaseViewModel
{
public ISiteConfig SiteConfig { get; set; }
public BaseViewModel(ISiteConfig siteConfig)
{
this.SiteConfig = siteConfig;
}
}
And now let's create a model that inherits from it.
IndexViewModel
public class IndexViewModel : BaseViewModel
{
public string SomeIndexProperty { get; set; }
public IndexViewModel (ISiteConfig siteConfig) : base(siteConfig) {}
}
And now let's define a Base Controller that our Controllers will inherit from.
BaseController
public abstract class BaseController : Controller
{
protected BaseController(ISiteConfig siteConfig)
{
_siteConfig = siteConfig;
}
private readonly ISiteConfig _siteConfig;
public ISiteConfig SiteConfig
{
get
{
return _siteConfig;
}
}
}
Now we define our actual controller.
HomeController
public HomeController: BaseController
{
public HomeController(ISiteConfig siteConfig): base(siteConfig) {}
}
Assuming we're using Ninject for DI, Ninject would be configured to automatically create the Controller and pass a concrete ISiteConfig object into its Constructor at runtime.
Now we add our Action to the Controller.
Index Action
public ActionResult Index(IndexViewModel model)
{
return View(model);
}
And so this is the point where without doing anything else, MVC will explode with a "Parameterless Constructor" error if you try to call the Index Action, because MVC can't find a ViewModel constructor that takes no arguments.
And so, the answer. We need to override the default ModelBinder.
BaseViewModelBinder
public class BaseViewModelBinder : DefaultModelBinder
{
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
if (modelType == typeof(BaseViewModel) || modelType.IsSubclassOf(typeof(BaseViewModel)))
{
var baseControl = controllerContext.Controller as BaseController;
if (baseControl == null)
{
throw new Exception("The Controller must derive from BaseController");
}
var instance = Activator.CreateInstance(modelType, baseControl.SiteConfig);
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => instance, modelType);
return instance;
}
else
{
return base.CreateModel(controllerContext, bindingContext, modelType);
}
}
}
And we need to set this as the default model binder in global.asax.cs :
protected void Application_Start()
{
...
ModelBinders.Binders.DefaultBinder = new BaseViewModelBinder();
}
That's all. As you can see, when you view the Index Action now, MVC will use our custom model binder. It will realise that the IndexViewModel derives from BaseViewModel, and so will attempt to spin up an IndexViewModel instance using the ISiteConfig it can find in the Action's Controller (because the Controller derives from BaseController).
I'm [finally!] tackling MVC (version 3) after years of ASP.NET forms development. I have a strong background in n-tier application architecture, and I'm trying to approach this new project properly, with a clear separation of concerns, etc.
What I've done is start out with code-first by creating my POCOs. From this, the framework created my database.
Then, I implemented the Repository pattern by putting all my EF query and CRUD methods in a Repository class for each of my POCO classes in my Models assembly. This way, my Controllers don't need to know a thing about how I access my data via the EF. Great.
Finally, I created a few ViewModel classes in my Models assembly. My intent is, for certain actions (such as create and edit), I reference my ViewModel classes from the RAZOR views, instead of my POCO classes. This way, I can have my POCO class as well as a SelectList for populating a Drop Down within my ViewModel. Both populated by references to the associated Repository classes, which are called from my Controller Actions. I think I'm on a roll now:
class MyObject
{
public int ID {get;set}
[Required]
[StringLength(512)]
public string Name {get;set;}
}
class MyViewModel // ViewModel for a specific view
{
public MyObject MyModel {get;set;} // the model that is being edited
// other data the view might need, set by the controller
public string SomeMessage { get; set; }
public List<SomeObject> SomeObjects {get;set;} /// e.g. for a drop-down list
// My constructor below that populates the "SomeObjects" list, and accepts the
// "MyObject" class as a parameter in order to set the "MyModel" property above...
// ..........
}
The Problem...
Before I started using my ViewModel classes from my Controller Create and Edit actions, I passed in the POCO class directly. Everything worked fine when I hit the save button from my Edit form within my view:
Old Code:
[HttpPost]
public ActionResult Edit(MyObject mine)
{
if (ModelState.IsValid)
{
myRepository.Update(mine);
myRepository.SaveChanges();
return RedirectToAction("Index");
}
return View(mine);
}
When I hit save, my POCO class (MyObject) would be returned, automagically populated with values from the form, it would successfully save, and life was peachy.
When I switched to passing in my ViewModel (MyViewModel), everything fell apart.
I was able to refer to my ViewModel (MyViewModel) by setting the #model reference at the top of my Edit view. I was then able to populate my form fields from my POCO class (MyObject) that is part of the ViewModel. I was even able to populate the DropDownList from the SomeObjects collection in the ViewModel and preselect the correct one from my MyObject class I was editing. Everything seemed fine UNTIL...
When I hit the save button and my Controller's Edit ActionResult (POST action) was called, the MyObject class that is passed in to the ActionResult (public ActionResult Edit(MyObject mine)) was null.
Then, I tried changing the passed in object to my ViewModel (public ActionResult Edit(MyViewModel myVM)), which had the referenced MyObject class (MyModel) as null.
What am I missing?
I know it has to be something so incredibly simple that it's staring me in the face and I cannot see it!
Look at the FormCollection, the names of the keys should match the properties of the class you want to fill. This is how the default modelbinding of MVC works.
Wim,
Thanks so much for your help. I did have s parameter-less constructor, I had just omitted it from the example.
I actually tracked down the issue. In all fairness, the code I typed in was not the actual code since I didn't have it in front of me when I posted this. What the issue was is that my entity model class reference in my ViewModel actually had its set accessor as private:
public MyObject MyModel {get;private set;}
This had prevented the modelbinder from populating that property when posting back during the controller's save method.
What I'm left to do now is to move my validation logic from my EF POCO to my ViewModel, as seems to be the recommended action in this type of pattern.
Thanks for your time, and I hope this helps out other people with similar issues who are new to this framework.
I want to pass one of a number of classes that implement an interface from my view back to my controller action. I use an ActionLink in my view passing the instance to my action, but it naturally fails because MVC cannot deal with interfaces via default model binding.
So :
<%=Html.ActionLink(flow.Source.Name, "Get", new {container=flow.Source})%>
is in a loop and each flow.Source conforms to IContainer.
public class Flow
{
public virtual IContainer Source { get; private set; }
}
public interface IContainer
{
//members here
}
public class File : IContainer
{}
public class Worksheet : IContainer
{}
Basically I want to call an action method :
public ActionResult Get(IContainer container)
{
// Do something
}
The reason being that I need to retrieve the state of the current container passed to my action method from the database. I use NHibernate and have entities mapped on a table per entity, so have one for File and one for Worksheet for example, so need to able to decide which data access class to use. Make sense? Probably not!
Can this be done without moving towards a base class Container? Can I stick with an interface being passed to my action method and resolve the subtype instance passed in place of the interface?
Any help with this would be gratefully appreciated.
An interface needs 'some' concrete implementation to reference when you would call your class. I think judging by your post you are aware of this : )
With that said there is 'kinda' of an approach handled here where you just create your own model binder that has to know about (or how) to map to and create a concrete type (either directly or by dependency injection)
ASP.NET MVC - Custom Model Binder on Interface Type