You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MAUI启用编译绑定后资源字典加载异常问题求助

.NET MAUI编译绑定下BoxView高度动态变化失效(NuGet发布后)

问题背景

在.NET MAUI项目中启用编译绑定(通过项目文件设置<MauiEnableXamlCBindingWithSourceCompilation>true</MauiEnableXamlCBindingWithSourceCompilation>)后,原本正常运行的模板里BoxView控件高度无法动态调整。添加触发器修复后,本地项目引用或使用Debug DLL时功能正常,但发布为NuGet包到消费项目中就失效,已配置资源字典打包仍未解决。

处理方案

1. 修正资源字典打包配置

编译绑定对XAML资源的编译输出要求更严格,原配置中同时使用None和MauiXaml重复打包可能导致资源元数据丢失。修改项目文件,统一使用MauiXaml确保XAML被正确编译并打包:

<ItemGroup>
  <MauiXaml Include="Resources\CommonStyles.xaml" Generator="MSBuild:Compile" Pack="True" PackagePath="lib\$(TargetFramework)\Resources\" />
  <MauiXaml Include="Resources\CommonTemplates.xaml" Generator="MSBuild:Compile" Pack="True" PackagePath="lib\$(TargetFramework)\Resources\" />
</ItemGroup>

2. 优化触发器绑定逻辑,规避编译绑定跨元素引用限制

编译绑定模式下,Source={Reference}的跨元素绑定在NuGet发布后可能因元数据丢失失效。改为直接绑定到控件的BindableProperty,避免跨元素引用:

步骤1:在EntryField控件中添加BindableProperty

public bool IsLabelVisible
{
    get => (bool)GetValue(IsLabelVisibleProperty);
    set => SetValue(IsLabelVisibleProperty, value);
}

public static readonly BindableProperty IsLabelVisibleProperty =
    BindableProperty.Create(nameof(IsLabelVisible), typeof(bool), typeof(EntryField), true);

步骤2:修改BoxView的绑定和触发器

<BoxView
    AutomationId="BoxViewPlaceholder"
    IsVisible="{Binding IsLabelVisible, Converter={StaticResource InvertedBoolConverter}}"
    Style="{DynamicResource LabeledFieldPlaceholderBoxViewStyle}">
    <BoxView.Triggers>
        <DataTrigger TargetType="BoxView"
                     Binding="{Binding IsLabelVisible, Converter={StaticResource InvertedBoolConverter}}"
                     Value="True">
            <Setter Property="HeightRequest" Value="23"/>
        </DataTrigger>
        <DataTrigger TargetType="BoxView"
                     Binding="{Binding IsLabelVisible, Converter={StaticResource InvertedBoolConverter}}"
                     Value="False">
            <Setter Property="HeightRequest" Value="1"/>
        </DataTrigger>
    </BoxView.Triggers>
</BoxView>

3. 确保NuGet包包含完整编译产物

在项目文件中添加配置,确保所有必要的编译输出文件被打包:

<ItemGroup>
  <None Include="bin\$(Configuration)\$(TargetFramework)\*.dll" Pack="True" PackagePath="lib\$(TargetFramework)\" />
  <None Include="bin\$(Configuration)\$(TargetFramework)\*.pdb" Pack="True" PackagePath="lib\$(TargetFramework)\" Condition=" '$(Configuration)' == 'Debug' " />
  <None Include="bin\$(Configuration)\$(TargetFramework)\*.xml" Pack="True" PackagePath="lib\$(TargetFramework)\" />
</ItemGroup>

4. 统一消费项目编译绑定配置

在消费项目的csproj中明确启用编译绑定,确保和类库的编译环境一致:

<PropertyGroup>
  <MauiEnableXamlCBindingWithSourceCompilation>true</MauiEnableXamlCBindingWithSourceCompilation>
</PropertyGroup>

原问题相关代码

BoxView样式

<Style x:Key="LabeledFieldPlaceholderBoxViewStyle"
       TargetType="BoxView">
        <Setter Property="HeightRequest"
                Value="23"/>
        <Setter Property="Margin"
                Value="0, 0, 0, 0"/>
        <Setter Property="Color"
                Value="Transparent"/>
        <Setter Property="BackgroundColor"
                Value="Transparent"/>
</Style>

CommonTemplates.xaml

<ResourceDictionary
    x:Class="Same.Mobile.UI.Core.Resources.CommonTemplates"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:baseclasses="clr-namespace:Same.Mobile.UI.Core.BaseClasses"
    xmlns:behaviors="clr-namespace:Same.Mobile.UI.Core.Behaviors"
    xmlns:const="clr-namespace:Same.Mobile.UI.Core;assembly=Same.Mobile.UI.Core"
    xmlns:ctrls="clr-namespace:Same.Mobile.UI.Core.Controls;assembly=Same.Mobile.UI.Core"
    xmlns:helper="clr-namespace:Same.Mobile.UI.Core.Helpers;assembly=Same.Mobile.UI.Core"
    xmlns:model="clr-namespace:Same.Mobile.UI.Core.Abstractions.Models;assembly=Same.Mobile.UI.Core.Abstractions"
    xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit">

    <!--  ControlTemplate  -->
    <ControlTemplate x:Key="EntryFieldTemplate">
        <VerticalStackLayout
            x:DataType="ctrls:EntryField"
            ClassId="_entryFieldLayout"
            HorizontalOptions="{TemplateBinding Path=HorizontalOptions}"
            VerticalOptions="{TemplateBinding Path=VerticalOptions}"
            WidthRequest="{TemplateBinding Path=WidthRequest}">

            <!--  Label - visibility is determined by converter (see class)  -->
            <Label
                x:Name="_entryFieldLabel"
                AutomationId="LabelText"
                ClassId="_entryFieldLabel"
                Style="{TemplateBinding Path=LabelTextStyle}"
                Text="{TemplateBinding Path=LabelText}"/>

            <BoxView
                AutomationId="BoxViewPlaceholder"
                IsVisible="{Binding Path=IsVisible, Source={Reference Name=_entryFieldLabel}, Converter={StaticResource InvertedBoolConverter}}"
                Style="{DynamicResource Key=LabeledFieldPlaceholderBoxViewStyle}">
                <BoxView.Triggers>
                    <DataTrigger TargetType="BoxView"
                                 Binding="{Binding Path=IsVisible, Source={Reference Name=_entryFieldLabel}, Converter={StaticResource Key=InvertedBoolConverter}}"
                                 Value="True">
                        <Setter Property="HeightRequest"
                                Value="23"/>
                    </DataTrigger>
                    <DataTrigger TargetType="BoxView"
                                 Binding="{Binding Path=IsVisible, Source={Reference Name=_entryFieldLabel}, Converter={StaticResource Key=InvertedBoolConverter}}"
                                 Value="False">
                        <Setter Property="HeightRequest"
                                Value="1"/>
                    </DataTrigger>
                </BoxView.Triggers>
            </BoxView>

            <Entry
                AutomationId="FieldText"
                ClassId="_entryFieldEntry"
                HeightRequest="{TemplateBinding Path=FieldHeightRequest}"
                IsEnabled="{TemplateBinding Path=IsEnabled}"
                IsPassword="{TemplateBinding Path=IsPassword}"
                Keyboard="{TemplateBinding Path=Keyboard}"
                Placeholder="{TemplateBinding Path=Placeholder}"
                Style="{TemplateBinding Path=EntryStyle}"
                Text="{TemplateBinding Path=Text,
                                       Mode=TwoWay}"
                WidthRequest="{TemplateBinding Path=FieldWidthRequest}"/>

            <Label
                AutomationId="ValidationResult"
                IsVisible="{TemplateBinding Path=ValidationResult.IsValid,
                                            Converter={StaticResource Key=InvertedBoolConverter}}"
                Style="{DynamicResource Key=SmallValidationErrorLabelStyle}"
                Text="{TemplateBinding Path=ValidationResult,
                                       Converter={StaticResource Key=ValidationErrorsLabelConverter}}"/>
        </VerticalStackLayout>
    </ControlTemplate>
    <Style TargetType="ctrls:EntryField">
        <Setter Property="ControlTemplate"
                Value="{StaticResource Key=EntryFieldTemplate}"/>
    </Style>

</ResourceDictionary>

消费项目引用方式

<Application
    x:Class="CoreTestApp.App"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:commonResources="clr-namespace:Same.Mobile.UI.Core.Resources;assembly=Same.Mobile.UI.Core"
    xmlns:local="clr-namespace:CoreTestApp">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources/Styles/Colors.xaml" />
                <ResourceDictionary Source="Resources/Styles/Styles.xaml" />
                <commonResources:CommonStyles />
                <commonResources:CommonTemplates />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

原项目文件配置

<ItemGroup>
  <None Include="Resources\CommonStyles.xaml" Pack="True" PackagePath="buildTransitive\Resources\" />
  <None Include="Resources\CommonTemplates.xaml" Pack="True" PackagePath="buildTransitive\Resources\" />
</ItemGroup>
<ItemGroup>
  <MauiXaml Update="Resources\CommonStyles.xaml" Pack="True" PackagePath="buildTransitive\Resources\" />
  <MauiXaml Update="Resources\CommonTemplates.xaml" Pack="True" PackagePath="buildTransitive\Resources\" />
</ItemGroup>

内容的提问来源于stack exchange,提问作者Divyesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 22:48:10