dotnet / project-system

The .NET Project System for Visual Studio
MIT License
959 stars 385 forks source link

DependentUpon with msbuild expression for items in subfolder #7722

Open tbolon opened 2 years ago

tbolon commented 2 years ago

Visual Studio Version

Microsoft Visual Studio Enterprise 2022 Preview Version 17.0.0 Preview 6.0 VisualStudio.17.Preview/17.0.0-pre.6.0+31815.197 Microsoft .NET Framework Version 4.8.04084

Installed Version: Enterprise

Summary

I am trying to add a DependentUpon metadata for all files of a certain type to nest any .cs file under that item in solution explorer.

Suppose you want to nest all .cs files under files with the same name but .txt extension on the same location.

You can end up with the following csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <Compile Update="**/*.cs">
      <DependentUpon>$([MSBuild]::ValueOrDefault('%(Identity)', '').Replace(".cs",".txt").Replace("\","/"))</DependentUpon>
    </Compile>
  </ItemGroup>
</Project>

This change will work the first time you set it on visual studio for all files, even the files inside a subdirectory of the project.

But as soon as you close and relaunch VS, the files in the subdirectory will not be nested anymore.

As soon as you change the .Replace("\","/") expression to .Replace("/","\"), the files will be nested again, until you close and reopen VS, and you can change the expression again in the other way and VS will nest them again.

Steps to Reproduce

  1. Create a netstandard project
  2. Add a file Class1.cs and Class1.txt on the project
  3. Add a file Sub\Class2.cs and Sub\Class2.txt on the project
  4. Add a file NotNested.cs
  5. Change the .csproj to add the <Compile Update="**/*.cs">... expression from the Summary above
  6. Observe VS: the file Class2.cs will be nested under Class2.txt, the file Class1.cs also under Class1.txt
  7. Close and reopen VS: the file Class2 will not be nested anymore (Class1 will remain nested)
  8. Change the .csproj replace expression from .Replace("\","/") to .Replace("/","\")
  9. The file Class2.cs will be nested
  10. Close and reopen VS: the file is not nested anymore
  11. Rollback the change to the .csproj replace expression: the file will be nested
  12. Close and reopen VS: the file is not nested anymore
  13. Repeat :D

Expected Behavior

The file should remain nested after VS is closed and reopened, or the file should never been nested in the first place.

Actual Behavior

The file nesting for items in subfolder is not retained between VS instances.

User Impact

I want to create a nuget package with a source generator which add a DependentUpon on all custom files for partial class from the user.

pointnet commented 2 years ago
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <Compile Update="**\*.cs">
      <DependentUpon>$([System.String]::Copy('%(Filename)')).txt</DependentUpon>
    </Compile>
  </ItemGroup>

</Project>

My 2 cents!

Laniusexcubitor commented 2 years ago

See https://developercommunity.visualstudio.com/t/DependentUpon-not-working-on-project-loa/10034952

DependentUpon must only include a filename with extension, not a path.

ShadowMarker789 commented 1 month ago

I am having this issue with Xaml pages too.

    <ItemGroup>
        <Page Update="MainWindowStyles.xaml">
            <DependentUpon>MainWindow.xaml</DependentUpon>
        </Page>
    </ItemGroup>

Results in:

image

(Happy)

But then you restart visual studio!

Results in:

image

(Unhappy)

Confirmed in Visual Studio 17.8.3

ShadowMarker789 commented 1 month ago

I can also confirm this bug still exists in Visual Studio 17.10.0