WPF应用程序中的间歇性构建问题

dca*_*iro 18 c# wpf build

我有一个大型的WPF解决方案,可以运行2年.现在,当最奇怪的事情发生时,我们正在为该解决方案运行自动构建环境.

50%的构建中,我收到此错误:

例外:无法将类型为"System.Windows.Controls.StackPanel"的对象强制转换为"System.Windows.Controls.Border".标记文件中对象'System.Windows.Controls.StackPanel'出错...

看起来很简单.问题是我的代码背后是:

<UserControl x:Class="SiSM.Episode.Mishap.SpecializationList" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Converters="clr-namespace:Utils.Converters;assembly=Utils" ...>
    <Border x:Name="root"  BorderThickness="0.5">
        <StackPanel x:Name="stackPanelRoot" VerticalAlignment="Stretch">
            <Grid>
                ...
            </Grid>
            <StackPanel>
                ...
            </StackPanel>
            <ScrollViewer>
                ...
            </ScrollViewer>
        </StackPanel>
    </Border>
</UserControl>
Run Code Online (Sandbox Code Playgroud)

错误在这里,因为如果我切换dockpanel的stackpanel,错误消息将更改为dockpanel.

我的构建环境如下:

将代码复制到build文件夹:

private void CopyCode(string sourceDir, string destinationDir) {
            foreach (string dirPath in Directory.GetDirectories(sourceDir, "*", SearchOption.AllDirectories)) {
                if (!dirPath.Contains(".svn") && !dirPath.Contains(@"\bin") && !dirPath.Contains(@"\obj")) {
                    Directory.CreateDirectory(dirPath.Replace(sourceDir, destinationDir));
                }
            }

            foreach (string newPath in Directory.GetFiles(sourceDir, "*.*", SearchOption.AllDirectories)) {
                if (!newPath.Contains(".svn") && !newPath.Contains(@"\bin") && !newPath.Contains(@"\obj")) {
                    string dest = newPath.Replace(sourceDir, destinationDir);
                    File.Copy(newPath, dest);
                }
            }

            Worker.ReportProgress(5, "Copy done");
        }
Run Code Online (Sandbox Code Playgroud)

并构建解决方案:

private void Compile(string buildConfiguration) {
            Engine engine = new Engine();

            FileLogger logger = new FileLogger { Parameters = @"logfile=C:\builds\build.log" };
            engine.RegisterLogger(logger);

            BuildPropertyGroup bpg = new BuildPropertyGroup();
            bpg.SetProperty("Configuration", buildConfiguration, true);
            engine.GlobalProperties = bpg;

            var project = new Project(engine);
            project.Load(ProjectFilePath);

            bool success = engine.BuildProject(project);

            engine.UnregisterAllLoggers();
}
Run Code Online (Sandbox Code Playgroud)

这里有什么问题,或者WPF和Microsoft构建引擎有任何已知问题吗?

编辑1

我发现错误发生时.如果我第一次运行自动构建应用程序,它总是成功,但如果我运行它几秒钟时会发生上述错误.所以这可能是我忘了关闭那些造成错误的东西.

engine.Shutdown();在Compile方法的末尾添加了一个,但它没有解决问题.

编辑2

感谢@swiszcz的建议,发现了最奇怪的事情.文件SpecializationList.g.cs(在obj文件夹中)在第一次和第二次构建之间发生变化

第一次构建

void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
switch (connectionId)
{
case 1:
this.stackPanelRoot = ((System.Windows.Controls.StackPanel)(target));
return;
case 2:

#line 63 "..\..\..\Mishap\SpecializationList.xaml"
((System.Windows.Controls.Button)(target)).Click += new System.Windows.RoutedEventHandler(this.buttonShowGlobalView_Click);
...
Run Code Online (Sandbox Code Playgroud)

第二次构建

void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
switch (connectionId)
{
case 2:
this.stackPanelRoot = ((System.Windows.Controls.StackPanel)(target));
return;
case 3:
...
Run Code Online (Sandbox Code Playgroud)

它在切换条件下增加1,在第二次构建时,他无法将Button(情况2)转换为StackPanel(情况1).

Mac*_*ski 1

我的猜测:当我遇到一个非常类似的错误时,它是由 erroreus .g.cs 文件生成引起的。查看 .g.cs 文件以将 stackPanelRoot 转换为 Border。xaml 中的解决方法:将 x:Name="stackPanelRoot" 更改为 Name="stackPanelRoot",或者删除 x:Name(如果可能)。