tags:

views:

176

answers:

4

I've been trying for hours to get to the point where I can start a WPF application and have full control. I want to be able to create a ViewModel, create a View (Window), set the data context of the View to be the ViewModel, then show the View.

I've tried lots of methods, the most promising being to change the App.xaml to be a page and then adding my own Main method. Unfortunately this doesn't work properly because VS2010 then does not show the styles from the App.xaml in the designer, though they do work when running the app.

Is there a way to do what I want? If not, how do people normally start MVVM apps in WPF, creating a ViewModel outside of the View itself?

+1  A: 

The simplest way to assign an instance of the ViewModel to the DataContext of the view is in the code behind of the Window.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        DataContext = new myViewModel();
    }
}

For the first part of your question, you can have the control of your application in the StartUp event

<Application x:Class="myApplication.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml" Startup="Application_Startup">
    <Application.Resources>

    </Application.Resources>
</Application>

Code Behind :

public partial class App : Application
{
    private void Application_Startup(object sender, StartupEventArgs e)
    {
        // Place your code here
    }
}
Zied
+1  A: 

Hey Bill,

in our application, we have choosen the way which you already proposed: writing a new Main method. You also have to make some changes in the project application settings then (no startup object). The app xaml has to look something like this:

<Application  x:Class="EVOCURA.App"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Startup="Application_Startup"
            Exit="Application_Exit">

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>

            <!--Custom Controls-->
            <ResourceDictionary  Source="<your resources here>"/>


        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

The code behind will look something like this:

public sealed partial class App : Application
{
    static App()
    { }

    public App()
    { }

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        // create the main window and assign your datacontext
        MainAppWindow main = new MainAppWindow();
        main.DataContext = <your datacontext here>
        main.Show();
    }

    [STAThreadAttribute]
    public static int Main(string[] args)
    {
        App app = new App();

        app.InitializeComponent();
        app.Run();

        return 0;
    }
}

Have a look at the Startup Event and notice, that no default StartupUri is specified im App.xaml

You could also pass the DataContext in a new constructor of your MainWindow, or create the DataContext directly in xaml.

Hope this was helpful,

Jan

JanW
A: 

I would use the Startup event. You can add this to the App.xaml and remove the StartupUri line. When you add it, Visual Studio can create the event for you within the App.xaml.cs file. You can initialise your ViewModel and View within.

BlackWasp
D'Oh, I wish I have known about that. It's perfect, thanks!
Bill Jeeves
A: 

You can see the styles in the designer if you use DynamicResource in place of StaticResource.

amaca