Search code examples
wpfvisual-studiowindowmvp

How should I relate WPF MainWindow "mainloop" with application logic's "mainloop"


When we create a WPF project in Visual Studio (2010), it automatically creates a MainWindow.xaml, whose code-behind contains a MainWindow class with an InitializeComponent() in it. I know superficially that, somewhere in the project files, there is an actual main() function equivalent for the presentation, so that when the application GUI is loaded the GUI events are handled "downwards" the application layers - as soon as they exist.

I plan to develop something in the lines of Model-View-Presenter application, and I am already mocking very rudimentar domain-logic and application façade.

My doubt is: when I have my domain logic, how should I connect the Presenter with the Application Façade, or more pragmatically, WHERE and how (in the project files) I should start to "flesh out" the application from a blank WPF Application created in Visual Studio. I have made something like Add Existing Project, but than staled.

(EDIT: From a design patterns book: "An application facade is opened with a particular object in the domain model as the subject. This subject acts as the starting point for all the manipulations that are done by the facade." That seems a good start for the initiated...)

Is there any common, obvious or best-practice way of doing it?

(also, if someone could suggest / edit a better title for this question, I'd appreciate that)

Thanks for any help!


Solution

  • This guide from Microsoft (though a bit old) explains the layers and parts of a Rich Gui application rather well: http://msdn.microsoft.com/en-us/library/ee658087.aspx


    How you're actually structuring your projects and files is really up to you. You can build a stand-alone application in one project. You won't be able to re-use that code very easily, but your WPF application won't notice.

    You can group your classes in multiple ways. By Namespace, by assembly (project), nested class etc... When to use which is usually up to re-use or distribution over different machines.

    When you build a UI part and a webservice part, you'll probably stick each in a different project.

    When you want to re-use your business classes in a website and a windows app and a phone app, you'll probably want to stick them each in a different project.

    Separating into projects prevents you from creating circular dependencies between classes.

    Usually you'll get a chain of projects from the UI referencing the Business Layer referencing the Data layer etc. And you'll often see a couple of cross cutting concerns (logging and security for example) that are references from each of these 'layers'.

    In the end, a layer can map to a Project (assembly) or a Namespace (within a project). Which one you choose is up to you.


    In a WPF project the application entry point is specified by the App.Xaml. You'll find a reference to the main Form to load in there.

     <Application x:Class="WpfApplication1.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml"> <-- Start up here -->
        <Application.Resources>
    
        </Application.Resources>
     </Application>
    

    The actual entry point is defined in your project settings: Start Up Object

    You can start any initialization code in the App.xaml.cs. The simplest way is by subscribing to the OnStart event or the OnLoadCompleted event. You can also start your logic in the MainWindow.xaml.cs code. Place the actual logic in a separate class and reference that from your OnStart or OnLoadCompleted events.

    StartUp event

    And add your own code there

    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
    
        private void Application_Startup(object sender, StartupEventArgs e)
        {
    
        }
    }
    

    A better, more object oriented and unit testable way is to use Prism or MVVM Light. The scope of these frameworks is so large that they warrant their own topic.

    I'm not sure why you would want a mainloop. Unless you plan to do some kind of game or 3d rendering. In the other cases you can suffice by adding commands to the visible objects and let Windows handle the primary input registration and dispatching of events. For long-running tasks you can use threading to have that done in the background (different topic again).