2016-11-08 50 views
1

我有這個奇怪的錯誤。當我構建我的項目時,它總是彈出我的單例窗口的兩個實例。它發生的Here is video。雖然我認爲這不會有幫助,但這裏是窗口的大部分內容。在後面的代碼中,只是鼠標移動和關閉事件的事件。構建時的視覺工作室錯誤

<Window x:Class="Scoreboard.OutputWindow" 
    d:DataContext="{d:DesignInstance viewModel:ControlPanel}" 
    Title="OutputWindow" Height="375" Width="540" 
    Background="{Binding AppData.Settings.Color, Converter={converters:ColorToBrushConverter}}" 
    MouseLeftButtonDown="football_MouseLeftButtonDown" 
    MouseLeftButtonUp="football_MouseLeftButtonUp" 
    MouseMove="football_MouseMove"> 
    <Window.InputBindings> 
     <KeyBinding Modifiers="Control" Key="F" Command="{Binding FullScreenCommand}" /> 
    </Window.InputBindings> 
    <Grid ...> 
    </Grid> 
</Window> 

這個窗口是我的ViewModel中的一個單例。我從那裏訪問它。它發生在我的兩臺PC上。

編輯: 當我從ViewModel中刪除它時,它不再發生。但我有點需要它。 EDIT2:Here is帶有該窗口的新項目。它的行爲不完全相同,但是當你做了一些修改以便建立在調試上時,然後在sturtup上創建另一個OutputWindow,它不會被構造函數中的斷點捕獲。

+0

您是否在構造函數中設置了斷點以查看第二個實例的創建位置? – ChrisF

+1

它只是建立,它甚至不會啓動。這兩個例子都不應該在那裏。 – Korhak

+0

在項目的屬性中是否有任何「生成事件」? (尤其是任何生成後的命令。) – haindl

回答

1

你的問題的根本原因是在你的ViewModel以下行:

public ViewModel() 
{ 
    OutputWindow.IsEnabled = true; 
} 

這暗中創建的屬性的getter一個new OutputWindow()

private OutputWindow _outputWindow; 
public OutputWindow OutputWindow => 
    _outputWindow ?? (_outputWindow = new OutputWindow { DataContext = this }); 

然後構造看起來是這樣的:

public OutputWindow() 
{ 
    InitializeComponent(); 
    Show(); 
} 

這不會是

<Window.DataContext> 
    <local:ViewModel /> 
</Window.DataContext> 

好吧,這解釋了爲什麼OutputWindow是否顯示在啓動時:因此現在每次你MainWindow被實例化的ViewModel一個新的實例是隱式創建的,因爲這個代碼在MainWindow以及時間差,但 - 但爲什麼它會顯示構建?
(或者,即使你開的MainWindow.xaml Visual Studio中的XAML代碼我的情況)

如果找到了罪魁禍首,它是在這裏這個小寶石從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() 

那麼,爲什麼它發生了嗎?
在構建或打開XAML設計器時,Visual Studio啓動一個線程並指示XDesProc.exe創建MainWindow的新實例。
XDesProc.exe是負責在Visual Studio中,也許是設計師的XAML的設計師,如果你建立一個項目應該刷新的組件。)

從那裏上,該方式是如上圖所示:
ViewModelMainWindow的隱式DataContext中創建,它在屬性的獲取程序中隱式創建OutputWindow的新實例,該實例本身又調用Show()。瞧,你的屏幕上有你的OutputWindow
在某些情況下,甚至有兩個OutputWindows顯示,但這只是因爲設計者(或可能是另一個組件)被稱爲兩次。

所以,底線 - 你需要什麼來修復你的代碼?
有多種可能的解決方案。
最重要的是,您應該停止在ViewModel中隱式創建OutputWindow。您可以通過執行以下操作的一個(或多個)實現這一點:

  • ViewModel構造函數刪除OutputWindow.IsEnabled = true;
  • 不要在OutputWindow的構造函數中調用Show();
  • 請勿使用<Window.DataContext><local:ViewModel />隱式實例化ViewModel

我認爲這是公平的說,如果你只是創建一個簡單的ViewModel的實例,隱式地顯示一個窗口只是明顯錯誤。所以,如果你打破這種不幸的隱性事件鏈,那麼你的問題將永遠消失。

+0

謝謝,很好的詳細描述發生了什麼。 'OutputWindow.IsEnabled = true'就在那裏,所以getter被調用。正如你寫的,我從構造函數中移除了'Show()',並在'MainWindow'初始化之後移動了它並解決了問題。榮譽給你。 – Korhak

+0

@Korhak非常歡迎!很高興我能幫助你! :-) – haindl