JaneySprings / DotNet.Meteor

A VSCode extension that can run and debug .NET apps (Xamarin, MAUI, Avalonia)
https://marketplace.visualstudio.com/items?itemName=nromanov.dotnet-meteor
MIT License
269 stars 10 forks source link

[HotReload] Doesn't seem to work at all when the BindingContext is set to reference other elements on the page #85

Closed jedlimke closed 7 months ago

jedlimke commented 7 months ago

Hello again, @JaneySprings!

I think this may be related to https://github.com/JaneySprings/DotNet.Meteor/issues/83 but I figured I'd spin it out separately as to not cause more noise than I already probably have.

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 Bindings -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.

Importantly, however, I added a label within the XAML that has a BindingContext set to reference another element on the same page, the preceding button's text value. (e.g. <Label BindingContext="{x:Reference CounterBtn}" Text="{Binding Text}" />)

Everything still seems to work properly at this point.

However, once I add a second label that references a second button... then HotReload stops working until I comment the label out. I've attached two videos, one with one label, one with two, to demonstrate this behavior.

ONE LABEL VERSION: MainPage.xaml.cs:

namespace Bindings;

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);
  }
}

ONE LABEL VERSION: 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="Bindings.MainPage">
    <ScrollView>
        <VerticalStackLayout Padding="30,0"
                             Spacing="25">
            <Label Text="With Labels!"
                   Style="{StaticResource Headline}"
                   SemanticProperties.HeadingLevel="Level1" />

            <Button x:Name="CounterBtn"
                    Text="Click me"
                    SemanticProperties.Hint="Counts the number of times you click"
                    Clicked="OnCounterClicked"
                    HorizontalOptions="Fill" />
            <Label BindingContext="{x:Reference CounterBtn}"
                    Text="{Binding Text}" />
        </VerticalStackLayout>
    </ScrollView>
</ContentPage>

TWO LABEL VERSION: MainPage.xaml.cs:

namespace Bindings;

public partial class MainPage : ContentPage {
  int count = 0;
  int countTwo = 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);
  }

  private void OnCounterClickedTwo(object sender, EventArgs e) {
    countTwo++;

    if (countTwo == 1)
      CounterBtnTwo.Text = $"Clicked {countTwo} time";
    else
      CounterBtnTwo.Text = $"Clicked {countTwo} times";

    SemanticScreenReader.Announce(CounterBtnTwo.Text);
  }
}

TWO LABEL VERSION: 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="Bindings.MainPage">
    <ScrollView>
        <VerticalStackLayout Padding="30,0"
                             Spacing="25">
            <Label Text="With Labels!"
                   Style="{StaticResource Headline}"
                   SemanticProperties.HeadingLevel="Level1" />

            <Button x:Name="CounterBtn"
                    Text="Click me"
                    SemanticProperties.Hint="Counts the number of times you click"
                    Clicked="OnCounterClicked"
                    HorizontalOptions="Fill" />
            <Label BindingContext="{x:Reference CounterBtn}"
                    Text="{Binding Text}" />

            <Line WidthRequest="100" />

            <Button x:Name="CounterBtnTwo"
                    Text="Click me"
                    SemanticProperties.Hint="Counts the number of times you click"
                    Clicked="OnCounterClickedTwo"
                    HorizontalOptions="Fill" />
            <Label BindingContext="{x:Reference CounterBtnTwo}"
                    Text="{Binding Text}" />
        </VerticalStackLayout>
    </ScrollView>
</ContentPage>

https://github.com/JaneySprings/DotNet.Meteor/assets/2490879/1196457d-75d9-4925-8c2e-13d027980ac4

https://github.com/JaneySprings/DotNet.Meteor/assets/2490879/572676d3-639b-4631-acf1-cbac64e1e187

JaneySprings commented 7 months ago

Nice catch! This is my mistake. I should use ‘Equals’:

https://github.com/JaneySprings/DotNet.Meteor/blob/798baeaf003449c5b57b491b5734b74cf10e86c4/src/DotNet.Meteor.HotReload/Extensions/MarkupExtensions.cs#L28

I will fix it, write tests and publish release tomorrow.

JaneySprings commented 7 months ago

Hi, @jedlimke! I fixed this issue in the 4.2.1 version. Check for the extension update in VSCode!

jedlimke commented 7 months ago

@JaneySprings Yep! It works. Thank you!