XAML 条件`DependentUpon`取决于文件的存在

m2xkgtsf  于 2023-05-27  发布在  其他
关注(0)|答案(1)|浏览(148)

我有一个针对多个平台的共享项目,其中一些文件专用于某些平台。这些可以是普通的C#类或标记文件。
我希望将这些文件分组到它们各自的.cs文件(前者)和.xaml文件(后者)下。
沿着xaml.cs之外,一些.xaml文件还可能有一个额外的.cs文件。目前这些都是硬编码的,以依赖于它们的.xaml对应物。通过以下配置,我可以获得标记文件所需的结果:

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

即:

- Page.xaml
  - Page.cs
  - Page.xaml.cs
  - Page.Android.cs

但是,如果我将项目配置为将文件分组到.cs文件下,则会得到以下标记结果:

- Page.xaml
  - Page.cs
     - Page.Android.cs
  - Page.xaml.cs

这是预期的,但不是期望的。
我可以定义某种条件来避免这种情况发生吗?
编辑:
为了说明,它是具有以下配置的.shproj

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

.porjitems文件中,.xaml.cs文件的配置如下:

<Compile Include="$(MSBuildThisFileDirectory)Pages\SomePage.xaml.cs">
  <DependentUpon>SomePage.xaml</DependentUpon>
</Compile>

该配置分别导致类/标记的以下输出:

- Page.xaml
  - Page.cs
     - Page.Android.cs
  - Page.xaml.cs

- Class.cs
  - Class.Android.cs

而以下是我试图达到的目标:

- Page.xaml
  - Page.cs
  - Page.Android.cs
  - Page.xaml.cs

- Class.cs
  - Class.Android.cs
tvokkenx

tvokkenx1#

当前代码问题:

**\*Android.cs将匹配Update中的Class.Android.csPage.Android.cs
每个Update覆盖DependentUpon元数据的先前值。最后一个UpdateClass.Android.cs设置了Class.cs,而Page.Android.cs设置了Page.cs--正如您所观察到的。

解决方案:

一种解决方案是只显式配置所有文件。

<Compile Include="$(MSBuildThisFileDirectory)Pages\Page.cs">
    <DependentUpon>Page.xaml</DependentUpon>
  </Compile>
  <Compile Include="$(MSBuildThisFileDirectory)Pages\Page.Android.cs">
    <DependentUpon>Page.xaml</DependentUpon>
  </Compile>
  <Compile Include="$(MSBuildThisFileDirectory)Pages\Page.xaml.cs">
    <DependentUpon>Page.xaml</DependentUpon>
  </Compile>
  <Compile Include="$(MSBuildThisFileDirectory)Class.Android.cs">
    <DependentUpon>Class.cs</DependentUpon>
  </Compile>

或者

<Compile Include="$(MSBuildThisFileDirectory)Pages\Page.cs" />
  <Compile Include="$(MSBuildThisFileDirectory)Pages\Page.Android.cs" />
  <Compile Include="$(MSBuildThisFileDirectory)Pages\Page.xaml.cs" />
  <Compile Include="$(MSBuildThisFileDirectory)Class.Android.cs" />

  <DependsOnPage Include="$(MSBuildThisFileDirectory)Pages\Page.cs" />
  <DependsOnPage Include="$(MSBuildThisFileDirectory)Pages\Page.Android.cs" />
  <DependsOnPage Include="$(MSBuildThisFileDirectory)Pages\Page.xaml.cs" />

  <DependsOnClass Include="$(MSBuildThisFileDirectory)Class.Android.cs" />

  <Compile Update="@(DependsOnPage)">
    <DependentUpon>Page.xaml</DependentUpon>
  </Compile>
  <Compile Include="@(DependsOnClass)">
    <DependentUpon>Class.cs</DependentUpon>
  </Compile>

这是手动维护,但如果项目不经常更改,它可能是可以接受的。
不需要手动干预的解决方案是可能的,但有点棘手。MSBuild有两个阶段:评估和执行。DependentUpon元数据需要在IDE UI的评估过程中进行设置,但不会反映它。目标直到执行阶段才“运行”,因此DependentUpon元数据的所有逻辑必须包含在“顶级”ItemGroupPropertyGroup元素中。
稍后我将尝试用一个工作示例来更新这个答案。

相关问题