2016-11-08 72 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