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

.NET MAUI中XAML Hot Reload自定义控件更新异常问题

.NET MAUI自定义控件XAML Hot Reload失效问题

我体验.NET MAUI已有数日,该框架取消了XAML设计器,开发应用GUI时完全依赖XAML Hot Reload功能,但实测该功能对自定义控件无法正常生效。
本次问题复现所用的演示控件参考自微软官方文档的ContentView示例,我以.NET MAUI默认项目模板为基础实现了该示例控件,随后复现了异常行为。

测试环境

  • Visual Studio 2022 (17.3.0 Preview 1.1)
  • Visual Studio 2022 (17.3.0 Preview 2.0)

复现场景

场景1

首次启动应用时,MainPage.xaml中未定义CardView实例。此时修改项目模板生成的MainPage.xaml样板代码可正常触发GUI刷新,例如修改Label控件的文本(将"Hello, World!"修改为"Hello, Maui!"),可通过Hot Reload功能正常更新标签显示内容。
该场景下向MainPage.xaml中新增CardView实例,可通过Hot Reload正常创建对应UI元素并更新GUI;修改官方文档中提及的CardTitle、CardDescription等可绑定属性也符合预期,GUI可通过Hot Reload同步更新。

场景2

该场景承接场景1:完成上述新增、编辑CardView的操作后关闭应用,重新启动实时调试器时,之前已添加的CardView在修改后无法再通过Hot Reload触发更新;但新增CardView元素仍可按场景1的预期正常工作,Label等内置核心控件不受该问题影响。

问题结论

应用启动时已存在于XAML视觉树中的自定义控件,无法通过Hot Reload功能响应修改更新。

待确认问题

  • 是否遗漏了该功能正常运行的必要配置?
  • 是否需要在csproj文件中添加特定属性或配置项?
  • 是否需要为自定义控件实现特定接口才能让Hot Reload正常工作?
  • 该问题是否属于当前预览版本的已知Bug?

复现代码

MauiProject.csproj

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

    <PropertyGroup>
        <TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net6.0-windows10.0.19041.0</TargetFrameworks>
        <OutputType>Exe</OutputType>
        <RootNamespace>MauiProject</RootNamespace>
        <UseMaui>true</UseMaui>
        <SingleProject>true</SingleProject>
        <ImplicitUsings>enable</ImplicitUsings>

        <!-- Display name -->
        <ApplicationTitle>MauiProject</ApplicationTitle>

        <!-- App Identifier -->
        <ApplicationId>com.example.mauiproject</ApplicationId>
        <ApplicationIdGuid>2357E05B-5E8B-45AE-8942-76AD07490831</ApplicationIdGuid>

        <!-- Versions -->
        <ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
        <ApplicationVersion>1</ApplicationVersion>
        <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
        <TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
        <Platforms>AnyCPU;x64</Platforms>

        <XamlDebuggingInformation>True</XamlDebuggingInformation>
        <DisableXbfLineInfo>False</DisableXbfLineInfo>
    </PropertyGroup>

    <ItemGroup>
        <!-- App Icon -->
        <MauiIcon Include="Resources\appicon.svg" ForegroundFile="Resources\appiconfg.svg" Color="#512BD4" />

        <!-- Splash Screen -->
        <MauiSplashScreen Include="Resources\appiconfg.svg" Color="#512BD4" BaseSize="128,128" />

        <!-- Images -->
        <MauiImage Include="Resources\Images\*" />
        <MauiImage Update="Resources\Images\dotnet_bot.svg" BaseSize="168,208" />

        <!-- Custom Fonts -->
        <MauiFont Include="Resources\Fonts\*" />

        <!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
        <MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
    </ItemGroup>

    <ItemGroup>
      <Compile Update="CardView.xaml.cs">
        <DependentUpon>%(Filename)</DependentUpon>
      </Compile>
    </ItemGroup>

    <ItemGroup>
      <MauiXaml Update="CardView.xaml">
        <Generator>MSBuild:Compile</Generator>
      </MauiXaml>
    </ItemGroup>

</Project>

MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             
             xmlns:local="clr-namespace:MauiProject"
             
             x:Class="MauiProject.MainPage">             
    <ScrollView>
        <HorizontalStackLayout 
            Spacing="25" 
            Padding="0">
            <VerticalStackLayout 
                Spacing="25" 
                Padding="30,0"
                
                VerticalOptions="Center">

                <local:CardView
                    HeightRequest="150"
                    CardTitle="Pre-existing card"
                    CardDescription="This cards already exists in the visual tree when the app is started">
                </local:CardView>

                <!--<local:CardView
                    HeightRequest="150"
                    CardTitle="Added card"
                    CardDescription="This card is commented out and can be added at runtime by uncommenting">
                </local:CardView>-->

                <Image
                    Source="dotnet_bot.png"
                    SemanticProperties.Description="Cute dot net bot waving hi to you!"
                    HeightRequest="200"
                    HorizontalOptions="Center" />

                <Label 
                    Text="Hello, World!"
                    SemanticProperties.HeadingLevel="Level1"
                    FontSize="48"
                    HorizontalOptions="Center" />

                <Label 
                    Text="Welcome to .NET Multi-platform App UI"
                    SemanticProperties.HeadingLevel="Level2"
                    SemanticProperties.Description="Welcome to dot net Multi platform App U I"
                    FontSize="18"
                    HorizontalOptions="Center" />

                <Button 
                    x:Name="CounterBtn"
                    Text="Click me"
                    SemanticProperties.Hint="Counts the number of times you click"
                    Clicked="OnCounterClicked"
                    HorizontalOptions="Center" />

            </VerticalStackLayout>
        </HorizontalStackLayout>
    </ScrollView>
 
</ContentPage>

CardView.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             
             x:Name="this"
             x:Class="MauiProject.CardView">
    <Frame BindingContext="{x:Reference this}"
           BackgroundColor="{Binding CardColor}"
           BorderColor="{Binding BorderColor}">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="21"/>
                <RowDefinition Height="84"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="80"/>
                <ColumnDefinition Width="120"/>
            </Grid.ColumnDefinitions>
            
            <Frame BorderColor="{Binding BorderColor, FallbackValue='Black'}"
                   BackgroundColor="{Binding BackgroundColor, FallbackValue='Transparent'}"
                   Margin="12"
                   Grid.Row="0" Grid.RowSpan="2"
                   Grid.Column="0">
                <Image Source="{Binding IconImageSource}" />
            </Frame>

            <Label Text="{Binding CardTitle, FallbackValue='Card Title'}" Grid.Row="0" Grid.Column="1" FontAttributes="Bold"></Label>

            <Label Text="{Binding CardDescription, FallbackValue='Card description text'}" Grid.Row="1" Grid.Column="1" />
        </Grid>
    </Frame>
</ContentView>

CardView.xaml.cs

namespace MauiProject;

public partial class CardView : ContentView
{
    public static readonly BindableProperty CardTitleProperty = BindableProperty.Create(nameof(CardTitle), typeof(string), typeof(CardView), string.Empty);

    public string CardTitle
    {
        get => (string)GetValue(CardView.CardTitleProperty);
        set => SetValue(CardView.CardTitleProperty, value);
    }

    public static readonly BindableProperty CardDescriptionProperty = BindableProperty.Create(nameof(CardDescription), typeof(string), typeof(CardView), string.Empty);

    public string CardDescription
    {
        get => (string)GetValue(CardView.CardDescriptionProperty);
        set => SetValue(CardView.CardDescriptionProperty, value);
    }


    public static readonly BindableProperty IconImageSourceProperty = BindableProperty.Create(nameof(IconImageSource), typeof(ImageSource), typeof(CardView), null);
    public ImageSource IconImageSource
    {
        get { return (ImageSource)GetValue(CardView.IconImageSourceProperty); }
        set { SetValue(CardView.IconImageSourceProperty, value); }
    }


    public static readonly BindableProperty IconImageBackgroundProperty = BindableProperty.Create(nameof(IconImageBackground), typeof(Color), typeof(CardView), Colors.Transparent);
    public Color IconImageBackground
    {
        get { return (Color)GetValue(CardView.IconImageBackgroundProperty); }
        set { SetValue(CardView.IconImageBackgroundProperty, value); }
    }


    public static readonly BindableProperty CardColorProperty = BindableProperty.Create(nameof(CardColor), typeof(Color), typeof(CardView), Colors.Gray);
    public Color CardColor
    {
        get { return (Color)GetValue(CardView.CardColorProperty); }
        set { SetValue(CardView.CardColorProperty, value); }
    }


    public static readonly BindableProperty BorderColorProperty = BindableProperty.Create(nameof(BorderColor), typeof(Color), typeof(CardView), Colors.Black);
    public Color BorderColor
    {
        get { return (Color)GetValue(CardView.BorderColorProperty); }
        set { SetValue(CardView.BorderColorProperty, value); }
    }


    public CardView()
    {
        InitializeComponent();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 20:06:25