Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

intermittent build problem in a WPF application

Tags:

c#

wpf

build

I have a large WPF solution running around for 2 years. Now we're running an automated build environment for that solution when the strangest thing happened.

In 50% of our builds, I get this error:

Exception: Unable to cast object of type 'System.Windows.Controls.StackPanel' to type 'System.Windows.Controls.Border'. Error at object 'System.Windows.Controls.StackPanel' in markup file ...

It seems simple enough. The problem is that my code behind is the following:

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

The error is here because if I switch the stackpanel for a dockpanel the error message changed to a dockpanel.

My build environment is the following:

Copy the code to a build folder:

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

And build the solution:

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

Is anything wrong here or is there any known problem with WPF and Microsoft build engine?

Edit 1

I found when the error occurs. If I run the automated build app for the first time, it always succeeds, but if I run it a seconds time the above error occurs. So that's probably something I forgot to close that's creating the error.

I added a engine.Shutdown(); at the end of the Compile method but it didn't fix the problem.

Edit 2

Thanks to @swiszcz suggestion, just found the weirdest thing. The file SpecializationList.g.cs (on obj folder) changes between the first and second build

First build

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);
...

Second Build

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

It increases 1 on the switch condition, and on the second build he's unable to convert a Button (case 2) to a StackPanel (case 1).

like image 822
dcarneiro Avatar asked Mar 25 '11 17:03

dcarneiro


People also ask

Is WPF still relevant 2022?

“WPF would be dead in 2022 because Microsoft doesn't need to be promoting non-mobile and non-cloud technology. But WPF might be alive in that sense if it's the best solution for fulfilling specific customer needs today. Therefore, having a hefty desktop application needs to run on Windows 7 PCs with IE 8.

Does WPF use DirectX?

WPF uses DirectX and attempts to provide a consistent programming model for building applications.

Is WPF front end?

WPF uses XAML as its frontend language and C# as its backend languages. WPF was introduced as a part of . NET Framework 3.0 as the Windows library to build Windows client apps and the next generation of Windows Forms. The current version of WPF is 4.5.


1 Answers

My gues: when I had a very simlilar error, it was caused by erroreus .g.cs file generation. Look in your .g.cs file for casting stackPanelRoot to Border. A walkaround in xaml: change x:Name="stackPanelRoot" to Name="stackPanelRoot", or remove x:Name, if possible.

like image 118
Maciek Świszczowski Avatar answered Sep 18 '22 09:09

Maciek Świszczowski