我有一个运行了 2 年的大型 WPF 解决方案。现在,当最奇怪的事情发生时,我们正在为该解决方案运行一个自动构建环境。
在我们 50% 的构建中,我收到此错误:
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 ...
看起来很简单。问题是我背后的代码如下:
<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>
这里出现错误是因为如果我将堆栈面板切换为停靠面板,则错误消息会更改为停靠面板。
我的构建环境如下:
将代码复制到构建文件夹:
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");
}
并构建解决方案:
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();
}
这里有什么问题吗,或者 WPF 和 Microsoft 构建引擎是否存在任何已知问题?
编辑 1
我发现错误发生的时候。如果我第一次运行自动构建应用程序,它总是成功,但如果我运行它几秒钟,就会发生上述错误。所以这可能是我忘记关闭导致错误的原因。
我在 Compile 方法的末尾添加了一个 engine.Shutdown();
但它没有解决问题。
编辑 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);
...
第二次构建
void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
switch (connectionId)
{
case 2:
this.stackPanelRoot = ((System.Windows.Controls.StackPanel)(target));
return;
case 3:
...
它在切换条件下增加 1,而在第二次构建时,他无法将 Button(案例 2)转换为 StackPanel(案例 1)。
最佳答案
我的猜测:当我遇到一个非常类似的错误时,它是由 erroreus .g.cs 文件生成引起的。查看 .g.cs 文件以将 stackPanelRoot 转换为 Border。 xaml 中的解决方法:将 x:Name="stackPanelRoot"更改为 Name="stackPanelRoot",或删除 x:Name(如果可能)。
https://stackoverflow.com/questions/5436134/