La cause racine de votre problème est la ligne suivante dans votre ViewModel
:
public ViewModel()
{
OutputWindow.IsEnabled = true;
}
Cela crée implicitement un new OutputWindow()
dans le getter de la propriété:
private OutputWindow _outputWindow;
public OutputWindow OutputWindow =>
_outputWindow ?? (_outputWindow = new OutputWindow { DataContext = this });
Le constructeur ressemble alors à ce :
public OutputWindow()
{
InitializeComponent();
Show();
}
Ce ne serait pas si mauvais au moment, mais chaque fois que votre MainWindow
est instancié, une nouvelle instance de ViewModel
est implicitement créé et à cause de ce code dans le MainWindow
:
<Window.DataContext>
<local:ViewModel />
</Window.DataContext>
D'accord, ce qui explique pourquoi le OutputWindow
est apparaître au démarrage - Mais pourquoi cela se voit-il sur la construction?
(. Ou dans mon cas, même si vous ouvrez le code XAML de MainWindow.xaml
dans Visual Studio)
Si trouvé le coupable et il est ce petit bijou ici qui provient de devenv.exe
:
TestApplication.exe!TestApplication.OutputWindow.OutputWindow() Line 15
TestApplication.exe!TestApplication.ViewModel.OutputWindow.get() Line 6
TestApplication.exe!TestApplication.ViewModel.ViewModel() Line 10
...
mscorlib.dll!System.Activator.CreateInstance(System.Type type, bool nonPublic)
...
Microsoft.VisualStudio.DesignTools.Platform.dll!Microsoft.VisualStudio.DesignTools.Platform.InstanceBuilders.ClrObjectInstanceBuilder.Instantiate(Microsoft.VisualStudio.DesignTools.Platform.InstanceBuilders.IInstanceBuilderContext context, Microsoft.VisualStudio.DesignTools.Platform.InstanceBuilders.ViewNode viewNode = {Microsoft.VisualStudio.DesignTools.Platform.InstanceBuilders.ViewNode}) Unknown
Microsoft.VisualStudio.DesignTools.Platform.dll!Microsoft.VisualStudio.DesignTools.Platform.InstanceBuilders.ViewNodeManager.CreateInstance(Microsoft.VisualStudio.DesignTools.Platform.InstanceBuilders.IInstanceBuilder builder, Microsoft.VisualStudio.DesignTools.Platform.InstanceBuilders.ViewNode viewNode) Unknown
Microsoft.VisualStudio.DesignTools.Platform.dll!Microsoft.VisualStudio.DesignTools.Platform.InstanceBuilders.ViewNodeManager.Instantiate(Microsoft.VisualStudio.DesignTools.Platform.InstanceBuilders.ViewNode viewNode = {Microsoft.VisualStudio.DesignTools.Platform.InstanceBuilders.ViewNode}) Unknown
...
XDesProc.exe!Microsoft.VisualStudio.DesignTools.DesignerContract.Isolation.DesignerProcess.RunApplication()
...
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart()
Alors, pourquoi ça arrive?
Lors de la construction ou à l'ouverture du concepteur XAML, Visual Studio démarre un thread et demande à XDesProc.exe
de créer une nouvelle instance de votre MainWindow
.
(XDesProc.exe
est le composant qui est responsable du concepteur XAML dans Visual Studio et peut-être le concepteur devrait rafraîchir si vous construisez un projet.)
Et à partir de là, le chemin est comme indiqué ci-dessus:
Une nouvelle ViewModel
est créé dans le DataContext
implicite du MainWindow
qui crée implicitement une nouvelle instance du OutputWindow
dans le getter de la propriété qui à son tour appelle Show()
sur lui-même. Et voilà, vous avez votre OutputWindow
à l'écran!
Dans certains cas, il y a même deux OutputWindows
montrant mais c'est seulement parce que le concepteur (ou peut-être un autre composant) est appelé deux fois.
Alors, bottom line - De quoi avez-vous besoin pour corriger votre code?
Il existe plusieurs solutions possibles.
Le plus important, vous devez arrêter la création implicite du OutputWindow
dans le ViewModel
. Vous pouvez y parvenir en faisant un (ou plusieurs) des éléments suivants:
- Retirez
OutputWindow.IsEnabled = true;
dans le constructeur de ViewModel
. Ne pas appeler Show();
dans le constructeur de OutputWindow
. Ne pas instancier votre ViewModel
implicitement en utilisant <Window.DataContext><local:ViewModel />
.
Je pense qu'il est juste de dire qu'il est tout simplement faux de montrer implicitement une fenêtre si vous venez de créer une instance d'un simple ViewModel. Donc, si vous rompez cette chaîne malencontreuse d'événements implicites, votre problème disparaîtra pour toujours.
Avez-vous défini un point d'arrêt dans le constructeur pour voir d'où provient la seconde instance? – ChrisF
C'est juste de construire, ça ne commence même pas. Les deux instances ne devraient pas être là. – Korhak
Avez-vous des 'Build Events' dans les propriétés du projet? (Surtout les commandes post-construction.) – haindl