2010-08-09 4 views
18

Ich habe seit Stunden versucht, zu dem Punkt zu kommen, wo ich eine WPF-Anwendung starten und die volle Kontrolle haben kann. Ich möchte in der Lage sein, ein ViewModel zu erstellen, eine Ansicht (Window) zu erstellen, den Datenkontext der View als ViewModel festzulegen und dann die View anzuzeigen.Gibt es eine Möglichkeit, eine WPF-Anwendung ohne StartUpUri zu starten, die etwas anderes nicht unterbricht?

Ich habe viele Methoden ausprobiert, die vielversprechendste war, die App.xaml zu einer Seite zu ändern und dann meine eigene Main-Methode hinzuzufügen. Leider funktioniert das nicht richtig, da VS2010 die Stile aus der App.xaml im Designer nicht anzeigt, obwohl sie beim Ausführen der App funktionieren.

Gibt es eine Möglichkeit zu tun, was ich will? Wenn nicht, wie starten Benutzer normalerweise MVVM-Apps in WPF, indem sie ein ViewModel außerhalb der View selbst erstellen?

+1

Sie können die Stile im Designer anzeigen, wenn Sie DynamicResource anstelle von StaticResource verwenden. – amaca

Antwort

20

Ich würde das Startup-Ereignis verwenden. Sie können dies der App.xaml hinzufügen und die StartupUri-Zeile entfernen. Wenn Sie es hinzufügen, kann Visual Studio das Ereignis für Sie in der App.xaml.cs-Datei erstellen. Sie können Ihr ViewModel und View innerhalb davon initialisieren.

+0

D'Oh, ich wünschte, ich hätte davon gewusst. Es ist perfekt, danke! –

+12

Zukünftige Leser, beachten Sie, dass Sie ein NEW-Ereignis zuweisen müssen. Verwenden Sie NICHT die Methode 'protected override void OnStartup (StartupEventArgs e)', da in .NET 4.5 ein bekannter Fehler bekannt ist, bei dem der Compiler statische Ressourcen, die Sie in App.xaml angegeben haben, nicht laden kann. http://stackoverflow.com/questions/543414/wpf-app-xaml-file-does-not-get-parsed-if-my-app-does-not-set-a-startupuri – Heliac

1

Die einfachste Möglichkeit, dem DataContext der Ansicht eine Instanz des ViewModel zuzuweisen, befindet sich im Code hinter dem Fenster.

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

     DataContext = new myViewModel(); 
    } 
} 

Zum ersten Teil Ihrer Frage, können Sie die Kontrolle haben Ihre Anwendung in dem StartUp Ereignisse

<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 
    } 
} 
+0

Alles hängt davon ab, was Ihr Ansichtsmodell erstellen muss. Wenn Sie einen leeren Contructor haben, funktioniert das gut. Wenn nicht, ist es nicht so hübsch. – digitalMoto

+0

Ich habe begonnen, eine ViewModel-Eigenschaft zu ViewWindow mit den erforderlichen Kompositionsdekorationen hinzuzufügen. Die tatsächliche Klasse für die VM ist explizit, aber alle meine Ansichten haben eine Eigenschaft "ViewModel". Bis jetzt macht es das Leben viel einfacher und respektiert die Grenze zwischen View und ViewModel. Ich benutze einen Prism-Bootstrapper an diesem Punkt, so dass ich App.xaml nie über StartupUri zu meiner Shell aufrufen lassen. digitalMoto

2

in unserer Anwendung, Wir haben den Weg gewählt, den Sie bereits vorgeschlagen haben: eine neue Main-Methode schreiben. Sie müssen dann auch einige Änderungen in den Projektanwendungseinstellungen vornehmen (kein Startobjekt). Die App XAML hat so etwas wie folgt aussehen:

<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> 

Der Code hinter wird wie folgt aussehen:

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; 
    } 
} 

Werfen Sie einen Blick auf die Startup-Ereignis und Ankündigung, dass kein Standard StartupUri wird im App.xaml

angegeben Sie können den DataContext auch in einem neuen Konstruktor Ihres MainWindow übergeben oder den DataContext direkt in Xaml erstellen.

19

Hier ist eine einfache Art und Weise ...

<Application 
    x:Class="Demo.Ux.WpfApp.App" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
</Application> 

Hier wird der Grund App.xaml.cs ist

public partial class App 
{ 
    protected override void OnStartup(StartupEventArgs e) 
    { 
    try 
    { 
     var mainView = new MainView(); 
     mainView.Show(); 
     mainView.DataContext = new MainViewModel(); 
    } 
    catch (Exception ex) 
    { 
     Debug.WriteLine(ex); 
    } 
    } 
} 

Application.MainWindow können ebenfalls verwendet werden. Das erste angezeigte Fenster wird automatisch MainWindow zugewiesen. Natürlich können Sie die Erstellung Ihres mainView überspringen und direkt auf MainWindow schreiben, was auch die Syntax ausdünnen würde.

MainWindow = new MainView(); 
MainWindow.Show(); 
MainWindow.DataContext = new MainViewModel(); 

Eine letzte Anmerkung, ich tue das Show, bevor die Daten binden.Sie müssen dies tun, um eine Situation zu vermeiden, in der MainViewModel während der Erstellung eine Ausnahme auslöst. Wenn die MainView nicht angezeigt wurde, wird die App geschlossen, ohne dass Sie den Fehler sehen.

+0

Insgesamt ist dies besser als die akzeptierte Antwort. –

+3

!!! Tue es NICHT !!! Sie werden definitiv in Schwierigkeiten geraten, wenn Sie später Ressourcen in App.xaml hinzufügen möchten (siehe http://stackoverflow.com/questions/543414/wpf-app-xaml-file-does-not-get-parsed-if -my-app-does-not-set-a-startupuri) Die akzeptierte Antwort hat keinen solchen Nachteil. – Lu55

+1

Lu55 - Sie können dem App.xaml-Code Ressourcen ohne Probleme hinzufügen. Es hängt alles davon ab, wie viel Arbeit Sie tun möchten. Mein Verständnis der ursprünglichen Frage war: wie man ein Ansichts- und Ansichtmodell mit voller Steuerung außerhalb der normalen startupuri anstellt. Wenn Sie alles von Hand verdrahten wollen. Du kannst es schaffen. Sich über jede mögliche Variation der Nutzung Sorgen zu machen, ist nur Ärger zu borgen. – digitalMoto

Verwandte Themen