Caliburn.Micro: Create and Bind View programmatically - caliburn.micro

I am currently experimenting with view composition in Caliburn.Micro. I have a working example where I have multiple user control based views injected into my main shell via the "View.Model" attached property route. So far so good.
In my application proper I am working with a mixed environment of mainly WinForms, with some WPF, so there is no WPF "shell" for Caliburn to manage. I'd like to be able to create my views on demand and add them to placeholders in my WinForms app.
I would like to know how I go about creating a view (which will be a user control containing sub user controls) programmatically using Caliburn so that all conventions, model bindings and sub-view injection is carried out.

The Caliburn ViewModelBinder can be used to crank the handle once you have a view instance and a corresponding view-model. Calling Bind resolves injected views and applies convention based binding, etc:
SomeCompositionView view = new SomeCompositionView();
ISomeCompositionViewModel viewModel = IoC.Get<ISomeCompositionViewModel>();
ViewModelBinder.Bind(viewModel, view, null);
ElementHost.Child = view;

Code snippet from BootstrapperBase.DisplayRootViewFor:
var viewModel = IoC.GetInstance(viewModelType, null);
var view = ViewLocator.LocateForModel(viewModel, null, null);
ViewModelBinder.Bind(viewModel, view, null);
var activator = viewModel as IActivate;
if(activator != null)
activator.Activate();

Related

Using code-first approach,I don't have an edmx file. what's the alternative?

I'm fairly new to asp.net mvc, so please bear with me.
I want to implement a calendar functionality, and all the tutorials I've looked at use database-first approach and have the edmx file (Entity Data Model)
I'm using code first and what can I do regarding the code that references this edmx file? do I reference context instead?
example:
public JsonResult GetEvents()
{
//Here MyDatabaseEntities is our entity datacontext (see Step 4)
using (MyDatabaseEntities dc = new MyDatabaseEntities())
{
var v = dc.Events.OrderBy(a => a.StartAt).ToList();
return new JsonResult { Data = v, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
}
Sorry if this question is vague or not clear.
Thank you and I'd appreciate help!
In code first, you don't need an edmx file, because everything is in your own code. The basic building blocks are:
A class that inherits from DbContext. This will be equivalent to the MyDatabaseEntities class in your sample.
A set of entity classes. They basically just need to be plain classes with auto properties corresponding to your database columns. For built in conventions to work, you also need an ID, for instance an int property named Id
A set of properties on your DbContext class of type DbSet for every type T which is an entity you would like to query against. This is the Events property in your example.
In more advanced scenarios you customize the mappings beyond what the conventions can infer automatically. This can be done with attributes on your entity classes, or via a special set of APIs that can be called on your context at startup
Go to Sql server inside your database there is a folder Database Diagram, Right click New Database Diagram and explore it.

ASP.NET MVC Register custom Model Binder for all ViewModels

I have created a Custom Model Binder that works perfectly.
All my ViewModels extend the BaseViewModel however when I register the Model Binder for BaseViewModel it just doesn't run.
If I register every ViewModel "by hand" like the following line it works perfectly
ModelBinders.Binders[typeof(ArticlesViewModel)] = new ContextDataBinder();
What I need to know if there is a way to do that kind of registration for all my viewModels without register all viewModels one by one.
As it was commented in my original post you can register all the model blinders by replacing the default binder
ModelBinders.Binders.DefaultBinder = new ContextDataBinder();
However that didn't worked for my specific case because the ViewModels that the framework creates automatically always return the previous ViewModel (in searches for example it doesn't return me filtered results but all the results).
I ended up creating a List of types containing the type of only the ViewModels that actually need to pass trough the ModelBinder and with a foreach e register them all one by one.

Asp.net mvc razor - Send data to main layout

I am newbie in asp.net mvc.
I created an asp.net mvc4 empty application and added an entity model to it.
I have a layout page which I want to display menu categories,header,footer vb.But how can I send the data contains one more entity object(last posts,categories,tags) to layout page ?
Thanks
If you want to pass data (coming from database I assume) to the layout view you are facing a scenario where you have data that is passed to every page in your application. So what I would do is create a base controller from which all your controllers will inherit:
public class BaseController : Controller
{
public LayoutModel model;
public BaseController()
{
// Here you will use some business logic to populate your Layout Model
// You might also consider placing this model into the cache to prevent constant fetching of data from the database on each page request.
model = _service.Populate();
ViewBag.LayoutModel = model;
}
}
As you can see I used the constructor of the base controller to fetch the data needed for your layout view. I made a property named model and used some business logic method called Populate (you need to write this yourself) to populate the model variable. Then I place the model into the ViewBag.
Once I have this set up then every controller I make in my solution needs to inherit from the base controller:
public class HomeController : BaseController
{
// Controller code here...
}
which means that every controller can now access the model property from the base controller.
From here you can use the ViewBag.LayoutModel on each view like this (declare a local variable at the top of the view and cast it into the underlying type):
#{
LayoutModel MenuModel = ViewBag.LayoutModel;
}
and then use it like this:
#MenuModel.SomeProperty
This is just one of the ways to do it but there are other less/more complex ways. You need to do some research on your own and see which technique fits you the best...

Is there a way to instantiate an aspx page and walk through it's control collection outside of a web request

Some background on this question. I've built a webapp inside of SharePoint that walks a user through a series of forms. Each form is a ASP.NET page with a number of SharePoint and custom controls. As part of a new feature request(details not relevant here), I need to know what fields are on each form. I'm planning to maintain this data inside of a SharePoint list that other pieces of my code will access programatically.
Rather than maintaining this list by hand, I'd like to populate it in my deployment scripts (written in C#). What I'm hoping is possible is the create a new Page object for each one of my Pages, and then walk through it's Controls collection using some extension methods I've already built to find out which fields are on each form. Is there a good way to instantiate the Page object in this context? To be completely specific, the deployment code runs inside of a SharePoint event receiver, but if you're not familiar with SharePoint, it would be similar trying to accomplish the same thing inside of a console app.
Well, as long as you have access to your web application's assembly you can make the following using Reflection:
1) Load the assembly into memory.
Assembly asm = Assembly.LoadFrom(#"Your assembly path");
2) Query the types for each one of your pages:
var types = asm.GetTypes();
3) For each of your Type instances, get the constructor, invoke it, get the page's instance and then call your Helper methods.
t = types[0];
t.GetConstructor(new Type[] { });
t.GetMethod("Your Method").Invoke(t, object[] {});

Using the entity framework model to store textbox values

I am fairly new to ASP.NET and I am trying to figure out how to use the entity framework model to data from a textbox field and store it in an existing field in a database which is available to the application .
I looked around on the internet and some solutions were to use a detailView but that would require me to recode the entire page and I would like to avoid that.
Can anyone provide any inputs on how to go about that ?
Thanks !!
For an introduction to using EF with ASP.NET see the tutorials at http://asp.net/entity-framework/tutorials -- there are two series there for Web Forms and one for MVC. Both of them have examples of using textboxes.
var context = new MyEntities();
var myObject = new myObjectType();
myObject.myValue = myTextBox.Text;
context.myObjectTypes.Add(myObject);
context.SaveChanges();

Resources