使用新的 CSPROJ 格式时 code-behind 无法识别 WPF 控件
WPF controls not recognized in code-behind when using new CSPROJ format
我在 Visual Studio 2017 年使用新的 CSPROJ 格式创建了一个 WPF 应用程序。
来自
我可以成功构建并 运行 应用程序。但是,我有一个问题,代码编辑器无法识别放置在 XAML 中的任何控件,因此我在编辑器中遇到错误并且没有智能提示。
重现步骤
- 启动 VS 2017
- 创建一个新的 "WPF App (.NET Framework)" C# 项目
- 将 csproj 文件编辑为如下所示:
项目文件:
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<PropertyGroup>
<LanguageTargets>$(MSBuildExtensionsPath)$(VisualStudioVersion)\Bin\Microsoft.CSharp.targets</LanguageTargets>
<TargetFramework>net45</TargetFramework>
<ProjectGuid>{030D04DA-D603-4D4C-95F7-B6F725A6829E}</ProjectGuid>
</PropertyGroup>
<PropertyGroup>
<OutputType>WinExe</OutputType>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="MainWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Compile Update="**\*.xaml.cs" SubType="Designer" DependentUpon="%(Filename)" />
</ItemGroup>
<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System.Xaml" />
<Reference Include="WindowsBase" />
</ItemGroup>
</Project>
- 将名为 "button1" 的按钮添加到 MainWindow.xaml,如下所示:
MainWindow.xaml
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Name="button1" Width="100" Height="50">Click me!</Button>
</Grid>
</Window>
- 尝试在 "MainWindow.xaml.cs" 中的代码中设置按钮标题。
你会看到intellisense不识别按钮被定义:
但是,项目构建并 运行 成功(请注意,您需要手动 运行 可执行文件 - F5 不起作用。 .)
一个稍微复杂的解决方案是编辑项目文件以添加生成的 类。不幸的是,我不知道如何使文件依赖于 XAML 文件 - 我认为 that only works for files in the same folder.
此外,您需要使用 MSBuild:UpdateDesignTimeXaml
而不是 MSBuild:Compile
,如 here
所述
最后,您似乎必须明确命名 "Page" 元素中的每个 "Include" - 您不能使用通配符。
<Project>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</ApplicationDefinition>
<Page Include="MainWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</Page>
<Compile Update="**\*.xaml.cs" DependentUpon="%(Filename)" />
<!-- ADD THIS LINE HERE TO INCLUDE THE GENERATED PARTIAL CLASSES -->
<!-- ENSURE YOU ARE USING THE g.cs AND NOT g.i.cs FILES
OR YOU WILL GET A BUILD FAILURE -->
<Compile Include="$(IntermediateOutputPath)**\*.g.cs" />
</ItemGroup>
对您之前的答案稍作改进是包含 .g.cs 文件,但将它们标记为不可见,这样它们就不会显示在解决方案中。然后您还需要将 BaseIntermediateOutputPath 标记为不可见,否则它会显示为空文件夹。
这给出了相同的行为,但看起来更整洁,因为您没有在解决方案资源管理器中看到 obj 文件夹。
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="**\*.xaml" SubType="Designer" Generator="MSBuild:Compile" Exclude="App.xaml" />
<Compile Update="**\*.xaml.cs" SubType="Designer" DependentUpon="%(Filename)" />
<Compile Include="$(IntermediateOutputPath)*.g.cs" Visible="false" />
<None Include="$(BaseIntermediateOutputPath)" Visible="false" />
</ItemGroup>
我发现使用它来定义 Sdk 为我解决了这个问题:
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="MSBuild.Sdk.Extras">
<PropertyGroup>
....
而不是
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
....
(这是VS2017的15.9.15版本)
我在 Visual Studio 2017 年使用新的 CSPROJ 格式创建了一个 WPF 应用程序。
来自
我可以成功构建并 运行 应用程序。但是,我有一个问题,代码编辑器无法识别放置在 XAML 中的任何控件,因此我在编辑器中遇到错误并且没有智能提示。
重现步骤
- 启动 VS 2017
- 创建一个新的 "WPF App (.NET Framework)" C# 项目
- 将 csproj 文件编辑为如下所示:
项目文件:
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<PropertyGroup>
<LanguageTargets>$(MSBuildExtensionsPath)$(VisualStudioVersion)\Bin\Microsoft.CSharp.targets</LanguageTargets>
<TargetFramework>net45</TargetFramework>
<ProjectGuid>{030D04DA-D603-4D4C-95F7-B6F725A6829E}</ProjectGuid>
</PropertyGroup>
<PropertyGroup>
<OutputType>WinExe</OutputType>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="MainWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Compile Update="**\*.xaml.cs" SubType="Designer" DependentUpon="%(Filename)" />
</ItemGroup>
<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System.Xaml" />
<Reference Include="WindowsBase" />
</ItemGroup>
</Project>
- 将名为 "button1" 的按钮添加到 MainWindow.xaml,如下所示:
MainWindow.xaml
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Name="button1" Width="100" Height="50">Click me!</Button>
</Grid>
</Window>
- 尝试在 "MainWindow.xaml.cs" 中的代码中设置按钮标题。
你会看到intellisense不识别按钮被定义:
但是,项目构建并 运行 成功(请注意,您需要手动 运行 可执行文件 - F5 不起作用。 .)
一个稍微复杂的解决方案是编辑项目文件以添加生成的 类。不幸的是,我不知道如何使文件依赖于 XAML 文件 - 我认为 that only works for files in the same folder.
此外,您需要使用 MSBuild:UpdateDesignTimeXaml
而不是 MSBuild:Compile
,如 here
最后,您似乎必须明确命名 "Page" 元素中的每个 "Include" - 您不能使用通配符。
<Project>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</ApplicationDefinition>
<Page Include="MainWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</Page>
<Compile Update="**\*.xaml.cs" DependentUpon="%(Filename)" />
<!-- ADD THIS LINE HERE TO INCLUDE THE GENERATED PARTIAL CLASSES -->
<!-- ENSURE YOU ARE USING THE g.cs AND NOT g.i.cs FILES
OR YOU WILL GET A BUILD FAILURE -->
<Compile Include="$(IntermediateOutputPath)**\*.g.cs" />
</ItemGroup>
对您之前的答案稍作改进是包含 .g.cs 文件,但将它们标记为不可见,这样它们就不会显示在解决方案中。然后您还需要将 BaseIntermediateOutputPath 标记为不可见,否则它会显示为空文件夹。
这给出了相同的行为,但看起来更整洁,因为您没有在解决方案资源管理器中看到 obj 文件夹。
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="**\*.xaml" SubType="Designer" Generator="MSBuild:Compile" Exclude="App.xaml" />
<Compile Update="**\*.xaml.cs" SubType="Designer" DependentUpon="%(Filename)" />
<Compile Include="$(IntermediateOutputPath)*.g.cs" Visible="false" />
<None Include="$(BaseIntermediateOutputPath)" Visible="false" />
</ItemGroup>
我发现使用它来定义 Sdk 为我解决了这个问题:
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="MSBuild.Sdk.Extras">
<PropertyGroup>
....
而不是
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
....
(这是VS2017的15.9.15版本)