I need reading material on how modelmetadata is populated and when the OnMetadataCreated method is called in the framework. When I created a viewmodel that contains a nested viewmodel, OnMetadataCreated was not called for the properties of the inner viewmodel, but it was created for the properties in the outermodel.
My current solution circumvents this by using reflection in the view to access the properites and attributes of the inner view model. (Normally I would access these attributes and do things with them in the OnMetadataCreated.)
Related
I am moving my application development from WPF via Xamarin.Forms to Xamarin.Mac.
I have a nested view model structure with view models exposing child view models via properties. Nested UI elements are bound to the view model properties exposed by the containing view model.
For example:
ViewModel_1 bound to View_1
ViewModel_11 bound to View_11
ViewModel_12 bound to View_12
These view models are the DataContext of nested UserControls in WPF and the BindingContext of nested ContentViews in Xamarin.Forms.
What is the corresponding approach when working with Xamarin.Mac? I am not asking about the specifics of data binding (though I will need to get a handle on this), more the UI structure. Is it done by using nested view controllers? Nested views?
I am using Xcode Interface Builder to construct the UI.
If I am barking up the wrong tree, what is the right approach?
Turns out what I am after is a Container View. Tutorial here.
A container view is a placeholder for another view and comes with its own View Controller.
I have seen many posts about when to use ViewBag/ViewData vs ViewModel but i have not been able to find an explanation of the lifecycle of the ViewBag.
For example, i have two Action methods in one Controller:
// POST: /MyModel/Edit/5
[HttpPost]
public ActionResult Edit(MyModel _mymodel){}
and
// GET: /MyModel/Edit/5
public ActionResult Edit(int id){}
If i put some values in the ViewBag in the GET action method, to set up some Form labels, then when they user clicks 'Submit' button and the Form is posted back to the server via HTTP POST, the ViewBag values are no longer within the POST action method.
Can someone please explain (or provide reference to good article) the lifecycle of the ViewBag/ViewData ?
The data you put in the ViewBag/ViewData is only available during the life-cycle of the request within which you populated it. MVC does not have post backs. If you need something to persist over more than a single request, you should use Session.
Here is a decent article about the differences between ViewData, ViewBag, and TempData: http://rachelappel.com/when-to-use-viewbag-viewdata-or-tempdata-in-asp.net-mvc-3-applications
The accepted answer here doesn't really describe the lifecycle of ViewBag/ViewData. It's unfortunate there appears to be no clear documentation about this. However, based on this:
http://blogs.msdn.com/b/varunm/archive/2013/10/03/understanding-of-mvc-page-life-cycle.aspx
It would seem the lifecycle is:
IIS request -> Routing -> MVC Handler -> Controller (with ViewData) -> View (with ViewData) -> Disposal
So, the ViewData (which ViewBag simply wraps) would actually be instantiated with the ControllerContext, at the same time TempData is instantiated. This occurs a few steps after Step 4: MVC Handler Executes.
There's an interesting step later where "If the Page has ViewData, the ViewData is set" during the handoff from Controller to View. ViewData is clearly available prior to this, so set can't mean instantiate. It appears to instead mean it's transferred from the Controller (which remember isn't available to a View) to the ViewContext (the container that provides the View access to ViewBag/ViewData, and Model).
The ViewData is presumably disposed of at the same time as the rest of the View.
It's important to also note that MVC Views are rendered from the inside out, so the particular View and any assignments it makes to the ViewBag will occur likewise in the order of inside to outside. That means something set on a View child page will be available to a Layout, but adding something to a ViewBag in a Layout and then reading it in a View child page will fail.
From MSDN - ViewBag: The dynamic view data dictionary, ViewData: The dictionary for the view data.
So these/this is a dictionary for a given view. You set its values in your action and you use it in your view. As Zach said it's not coming back with the subsequent request. You can send its values back to any given action as a form field, in querystring, etc, but these values won't be automatically available as VieBag's properties.
ViewBag and ViewData are used for the same purpose. They are used to pass data from controllers to the View. When we assign any data or object to them they are accessible in the View.
ViewData: ViewData is a dictionary of objects and they are
accessible by string as key.
ViewBag: Uses the dynamic feature. It allows an object to add
dynamic properties to it.
I want to make a partialview with 2 dropdownlists. DDL data have to generate from db. I am new in MVC. What will be the proper way to make this Partialview?
Thanks
(Assuming you're using Visual Studio)
Under Views folder in your project find a folder named "Shared" (or create it if doesn't exist). Right-click this folder, select "Add->View". In the dialog "Add View" specify view name, model type (if you wish) and set the checkbox "Create as a partial view". Model type should probably be a new model class with two List<string> elements.
Anywhere you need to use this view, include the markup
#Html.RenderPartial("YourPartialViewName", YourModel);
where YourModel has the same type as a model specified in partial view declaration.
From my experience it's better to create action and call RenderAction() passing relevant parameters than using RenderPartial(). The reason is that you need to pass a fully populated model to RenderPartial and that means you have to duplicate the code for populating this model in all the controllers that use this 'partial view'.
I found it much cleaner to create a separate action that can receive a number of parameters (ie. id of the object) and than perform all the required steps to populate the model (ie. load the object from database). You can mark that new action with ChildActionOnly attribute so it cannot be called directly.
I have an MVC3 project I'm working on that has a View with an associated strongly typed view model. I've been tasked with adding an optional section to this view that would contain the data for a second model, about half of which is shared with the first model.
My question is, what is the best way to implement this? Should I just add the object that the optional model represents to the view model and try to map values from there?
If I do it this way, how can I associate the editors with both models?
Adding the optional model to the view model is the best choice, because, unlike ViewBag, it's type safe and you can still leverage the html helpers. Just remember to check the second model for null reference before you render it (since it's optional).
For sharing properties, your view model can have special getters/setters that would mantain both models synchronized internally.
I think I understand what your asking and this is how I have accomplished it in the past.
Add the optional model as a parameter in the view model and then create a partial view that is typed to that optional model. If the criteria is met that allows that partial view to display then you pass the viewmodel.optionalmodel to that partial view.
You just have to be a bit careful about the overlap of parameters causing any headaches (as in null references)
Apple says:
An attribute of an NSController object. When binding to an NSController object, you use this field to select the first entry in the key path. The menu associated with this field displays the properties available on the selected controller object as a convenience. You can type the name of the property or simply select it from the provided list.
Can someone explain that in other words?
You are binding a view object to a model property. Something like (schematically):
myTextField.value <=> myModel.textValue.
While you can bind a view property directly to your model object's property like shown above, you really shouldn't. You would miss out on the nice features provided by Apple's controllers (e.g. NSObjectController, NSArrayController, etc.). Instead you should bind your view to a controller which is bound to the model, like:
myTextField.value <=> myObjectController.selection.textValue
and
myObjectController.contentObject <=> myModel
In this setup, myObjectController.selection is a Key-Value binding compatible proxy for myObjectController.contentObject and myObjectController can act as a mediator between the view and the model. Interface Builder makes this separation of concerns explicit because controllers may expose multiple proxies for their bound model (such as NSArrayController's arrangedObjects and selectedObjects). In binding myTextField.value in the example above, you would enter 'selection' in the "Controller Key" field and "textValue" in the "Model Object Keypath" path field.