Closed jpmock closed 7 months ago
Hi @jpmock! HotReload also works with CollectionView. Check the following demo:
https://github.com/JaneySprings/DotNet.Meteor/assets/48021947/bedb307c-2ab3-4e71-a9a1-c04bb2f9cb1f
Maybe you have an example to reproduce? It will be helpful
Here is one of my more basic pages which has a CollectionView:
`<?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:MyApp.Portable" BindingContext="{Binding WorkOrderDetailViewModel, Source={StaticResource ViewModelLocator}}" x:Class="MyApp.Portable.WorkOrderDetailPage" xmlns:zx="clr-namespace:ZXing.Net.Maui.Controls;assembly=ZXing.Net.MAUI.Controls" xmlns:behaviors="clr-namespace:MyApp.Portable.Behaviors;assembly=MyApp.PortableCore">
Wow, the code view above took all the nice formatting out of the xaml, sorry. If you put it into an IDE and click format it will show you better.
I appreciate you looking into this!. Let me know if you need more detail.
Can you try to set binding context from code behind (.xaml.cs
file) and remove this line:
BindingContext="{Binding WorkOrderDetailViewModel, Source={StaticResource ViewModelLocator}}"
@JaneySprings thank you for the suggestion! This works! We will certainly do this workaround to each page while we need hot reload and as long as it won't work using the ViewModelLocator. The ViewModelLocator gives us a couple things mainly, dependency injection and no code in the codebehind, but we will certainly give that up to have a working hot reload.
Thank you!!!!
No problem! I will check this behavior with a debugger, maybe I can fix it
Hi, @jpmock! I tried to create a simple example for this bug and I can't reproduce it. For example:
My view model and locator:
public class VMLocator {
public MyViewModel MyViewModel { get; }
public VMLocator() {
MyViewModel = new MyViewModel();
}
}
public class MyViewModel {
public string Text { get; set; }
public MyViewModel() {
Text = "Hello, Maui!";
}
}
App.xaml:
<Application.Resources>
<local:VMLocator x:Key="VMLocator" />
</Application.Resources>
MainPage.xaml:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MauiFlyoutApp"
x:Class="MauiFlyoutApp.MainPage"
BindingContext="{Binding MyViewModel, Source={StaticResource VMLocator}}">
<VerticalStackLayout>
<Label Text="{Binding Text}" />
</VerticalStackLayout>
</ContentPage>
Do you have any example project for this bug?
I'm on a Mac and am experiencing this behavior. I may be able to provide the example you seek, @JaneySprings.
I created a blank .NET MAUI app in an empty folder via the dotnet CLI as follows:
dotnet new install Microsoft.Maui.Templates.net8::8.0.7
dotnet new maui -n AlohaWorld -o .
This basic app, as generated by the template, is a "Hello, World" style app with a simple button whose label is updated with every click.
When debugging against an iOS simulator (17.2), I can confirm that, upon launch, clicking the button increments the counter and updates the label as expected.
However, when updates are made to the XAML for the MainPage
, the connection seems to become partially severed. The page does, indeed, update to reflect whatever changes I make to the XAML (changing the headline label, for example), but after that, clicking the button and firing the OnCounterClicked
event handler no longer results in button-label updates.
I can set a breakpoint in the OnCounterClicked
handler and see that the count
variable is incrementing as expected from the code-behind, but the button label, itself, can no longer be updated by setting CounterBtn.Text
.
This may not be exactly what @jpmock is experiencing, but I have a feeling it's pretty closely related and may have the same solution.
launch.json
:
{
"version": "0.2.0",
"configurations": [
{
"name": ".NET Meteor Debugger",
"type": "dotnet-meteor.debugger",
"request": "launch",
"preLaunchTask": "dotnet-meteor: Build"
}
]
}
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"
x:Class="AlohaWorld.MainPage">
<ScrollView>
<VerticalStackLayout
Padding="30,0"
Spacing="25">
<Image
Source="dotnet_bot.png"
HeightRequest="185"
Aspect="AspectFit"
SemanticProperties.Description="dot net bot in a race car number eight" />
<Label
Text="Aloha, World!"
Style="{StaticResource Headline}"
SemanticProperties.HeadingLevel="Level1" />
<Label
Text="Welcome to .NET Multi-platform App UI"
Style="{StaticResource SubHeadline}"
SemanticProperties.HeadingLevel="Level2"
SemanticProperties.Description="Welcome to dot net Multi platform App U I" />
<Button
x:Name="CounterBtn"
Text="Click me"
SemanticProperties.Hint="Counts the number of times you click"
Clicked="OnCounterClicked"
HorizontalOptions="Fill" />
</VerticalStackLayout>
</ScrollView>
</ContentPage>
MainPage.xaml.cs
:
namespace AlohaWorld;
public partial class MainPage : ContentPage
{
int count = 0;
public MainPage()
{
InitializeComponent();
}
private void OnCounterClicked(object sender, EventArgs e)
{
count++;
if (count == 1)
CounterBtn.Text = $"Clicked {count} time";
else
CounterBtn.Text = $"Clicked {count} times";
SemanticScreenReader.Announce(CounterBtn.Text);
}
}
MauiProgram.cs
:
using Microsoft.Extensions.Logging;
using DotNet.Meteor.HotReload.Plugin;
namespace AlohaWorld;
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
#if DEBUG
builder.EnableHotReload();
builder.Logging.AddDebug();
#endif
return builder.Build();
}
}
AlohaWorld.csproj
:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0-android;net8.0-ios;net8.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net8.0-windows10.0.19041.0</TargetFrameworks>
<OutputType>Exe</OutputType>
<RootNamespace>AlohaWorld</RootNamespace>
<UseMaui>true</UseMaui>
<SingleProject>true</SingleProject>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!-- Display name -->
<ApplicationTitle>AlohaWorld</ApplicationTitle>
<!-- App Identifier -->
<ApplicationId>com.companyname.alohaworld</ApplicationId>
<!-- Versions -->
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
<ApplicationVersion>1</ApplicationVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">11.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">13.1</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
</PropertyGroup>
<ItemGroup>
<!-- App Icon -->
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />
<!-- Splash Screen -->
<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="128,128" />
<!-- Images -->
<MauiImage Include="Resources\Images\*" />
<MauiImage Update="Resources\Images\dotnet_bot.png" Resize="True" BaseSize="300,185" />
<!-- Custom Fonts -->
<MauiFont Include="Resources\Fonts\*" />
<!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiVersion)" />
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="$(MauiVersion)" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
<PackageReference Include="DotNetMeteor.HotReload.Plugin" Version="3.*"/>
</ItemGroup>
</Project>
Hi, @jedlimke ! Thank you for the example. I know about this bug and I will try to fix it on the next weekend
Upd: I can fix this bug! This is not a best solution but it's better than nothing 😉
https://github.com/JaneySprings/DotNet.Meteor/assets/48021947/2a3d9c65-0ff9-482f-95f5-a0e9185026d5
Hi, @jedlimke ! Try to update .NET Meteor
to the 4.2.0
version and check this bug again.
@JaneySprings is this regarding the ViewmodelLocator bug or specific to @jedlimke issue? We will upgrade and try it anyway. Thanks
I think it's affected only @jedlimke issue. In your case there is something strange with ViewmodelLocator
after a page reload. If you can reproduce it with the simple app, please, let me know.
@JaneySprings Hello!
I updated to version 3.2.0
and can confirm that things are fixed for the issue I reported!
I assume that it is expected behavior, however, that I need to cause data to refresh in order to update the UI. That is, after a hot reload occurs, everything looks "broken" as before, but once I interact with the UI and cause data to change that's bound to the UI, the UI then reflects the correct data.
I've attached a video demonstrating the new behavior.
Is this expected behavior? It's certainly better than before.
https://github.com/JaneySprings/DotNet.Meteor/assets/2490879/baed229d-e645-4609-be78-1d960bd16962
Yes, it’s expected behavior, because a element (Button) resets all of its properties to the state, defined in the XAML file after reload.
Maybe there is a better solution (copy a state of the old element to the new element) but I can’t do it right now 🤔
OS: Mac
Hot reload does work but only works on very basic layouts. With anything remotely complex like items in a listview, it does not work, it actually causes the UI on the page to be all out of whack.