使用新的 CSPROJ 格式时 code-behind 无法识别 WPF 控件

WPF controls not recognized in code-behind when using new CSPROJ format

我在 Visual Studio 2017 年使用新的 CSPROJ 格式创建了一个 WPF 应用程序。

来自

我可以成功构建并 运行 应用程序。但是,我有一个问题,代码编辑器无法识别放置在 XAML 中的任何控件,因此我在编辑器中遇到错误并且没有智能提示。

重现步骤

  1. 启动 VS 2017
  2. 创建一个新的 "WPF App (.NET Framework)" C# 项目
  3. 将 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>
  1. 将名为 "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>
  1. 尝试在 "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版本)