views:

351

answers:

4

Hi,

I'm creating a wpf user control which is in mvvm pattern. So we have : view(with no code in codebehind file), viewmodel,model,dataaccess files.

I have MainWindow.xaml as a view file, which I need to bind with MainWindowModel.cs.

Usually, in a a wpf application we can do this with onStartUp event in App.xaml file. But in user control, as we do not have App.xaml...How do I achieve it ?

Please help :(...Thanks in Advance !!!

A: 

You can use a ContentControl, with a DataTemplate to bind the UserControl (View) to the ViewModel :

<DataTemplate DataType="{x:Type vm:MyViewModel}">
    <v:MyUserControl />
</DataTemplate>

...

<ContentControl Content="{Binding Current}" />

WPF will pick the DataTemplate automatically based on the type of the Content

Thomas Levesque
Dont we need any Property (dependency property or normal property )...in Content tag ?...Or How "Current" satisfies the same?
Anish
Hi Thomas, Can you please give me an idea about above query ?
Anish
In the code above, `Current` would be a property of the data context, of type `MyViewModel`
Thomas Levesque
Will it intiatiate the instance of class "MyViewModel" ?Also...hw the ContentControl know which DataTemplate it has to refer ?
Anish
No, it creates an instance of MyUserControl. Creating the instance of MyViewModel is your responsibility. The ContentControl picks the DataTemplate from the resources : it looks for a DataTemplate with the same DataType as the ViewModel and no x:Key attribute
Thomas Levesque
If I have to create instance of "MyViewModel" ...I have to create it in code-behind file of "View" right ?
Anish
I don't know the structure of your code, so I can't really answer that... You could create it in the "parent" ViewModel (that's what I usually do)
Thomas Levesque
+2  A: 

I've been using MVVM Light Toolkit which has a ViewModelLocator class that you can put properties to the viewmodels in. You then create a reference to the ViewModelLocator in your Mainwindow.xaml like so:

<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True"/>

In the grid panel, or whatever you're using, you can then set the datacontext like this:

<Grid DataContext="{Binding MainWindowViewModel, Source={StaticResource Locator}}">
...
</Grid>

You could also go with MEFedMVVM which potentially adds a bit more flexibility in terms of being able to swap different viewModel implementations into the view.

The flexibility in both of these libraries is that you don't have to use their ViewModel base classes if you don't want to - the ViewModelLocator and the MEFedMVVM can work with any class.

Dave Arkell
A: 

There are endless ways to do it, wich all fall in one of the two categories:"view first" or "model first".

In a "view first" mode the view (e.g. your mainwindow) is created first and then (e.g. in the codebehind) the View instantiates the ViewModel and sets it as its datacontext):

private void WindowLoaded(object sender, EventArgs args)
{
   this.DataContext = ViewModelService.GetViewModelX();
}

In a "model first" mode the ViewModel is there first and then instanciated the View.

// method of the viewmodel 
public void LoadView()
{
     // in this example the view abstracted using an interface
     this.View = ViewService.GetViewX();
     this.View.SetDataContext(this);
     this.View.Show();    
}

The examples given here are just one way of many. You could look at the various MVVM frameworks and see how they do it.

bitbonk
Thanks..I ll look in to it
Anish
Feel free to mark the answer you like as the accepted answer.
bitbonk
In MVVM model can we have code in code behind file of a view ?
Anish
Yes! A lot of implementations use the codebehind to wire-up the view with the viewmodel. For the sake of blendability and testability this should be kept at a minimum.
bitbonk
A: 

We can use ObjectDataProvider to call a method inside an object ..as follows :

Is there anyway to do the same using DataTemplate

Anish