Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x:Bind subscriptions should not linger after their target is unloaded #16405

Open
jeromelaban opened this issue Apr 22, 2024 · 2 comments
Open
Labels
area/xBind 🪢 Categorizes an issue or PR as relevant to x:Bind difficulty/tbd Categorizes an issue for which the difficulty level needs to be defined. kind/bug Something isn't working triage/untriaged Indicates an issue requires triaging or verification

Comments

@jeromelaban
Copy link
Member

Current behavior

x:Bind subscriptions are still raising property changes for unloaded controls

Expected behavior

Properties are not updated

How to reproduce it (as minimally and precisely as possible)

No response

Workaround

No response

Works on UWP/WinUI

None

Environment

No response

NuGet package version(s)

5.1.104

Affected platforms

No response

IDE

No response

IDE version

No response

Relevant plugins

No response

Anything else we need to know?

No response

@jeromelaban jeromelaban added kind/bug Something isn't working triage/untriaged Indicates an issue requires triaging or verification difficulty/tbd Categorizes an issue for which the difficulty level needs to be defined. labels Apr 22, 2024
@Youssef1313 Youssef1313 self-assigned this Apr 22, 2024
@Youssef1313 Youssef1313 added the area/xBind 🪢 Categorizes an issue or PR as relevant to x:Bind label Apr 22, 2024
@Youssef1313
Copy link
Member

Youssef1313 commented Apr 23, 2024

In WinUI, I see that the binding is still working, even after the control is unloaded.

XAML:

<Page x:Class="UnoApp14.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:UnoApp14"
      Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
  <StackPanel Margin="5" x:Name="sp">
    <TextBlock Text="{x:Bind VM.Value, Mode=TwoWay}" x:Name="myTb" />
    <Button Click="Button_Click">Click me</Button>
    <TextBlock Text="Logs:" x:Name="logTB" />
  </StackPanel>
</Page>

Code-behind:

//#define PUSH_FROM_VM_TO_CONTROL

using System.ComponentModel;

namespace UnoApp14;

public sealed partial class MainPage : Page
{
    private int counter;

    public MainPage()
    {
        this.InitializeComponent();
        VM = new VM(Log);

        myTb.Unloaded += myTb_Unloaded;
        myTb.RegisterPropertyChangedCallback(TextBlock.TextProperty, OnTextChanged);
    }

    private void Log(string text)
        => logTB.Text += "\r\n" + text;

    private void myTb_Unloaded(object sender, RoutedEventArgs e)
    {
        Log("TextBlock unloaded.");
    }

    private void OnTextChanged(DependencyObject sender, DependencyProperty dp)
    {
        Log("Text changed.");
    }

    public VM VM { get; }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Log("\r\nButton clicked");

#if PUSH_FROM_VM_TO_CONTROL
        VM.Value = (counter++).ToString();
#else
        myTb.Text = (counter++).ToString();
#endif

        if (counter == 5)
        {
            Log("Removing TextBlock.");
            sp.Children.Remove(myTb);
        }
    }
}

public class VM : INotifyPropertyChanged
{
    private readonly Action<string> _log;

    public VM(Action<string> log)
        => _log = log;

    public event PropertyChangedEventHandler? PropertyChanged;

    private string? _value;

    public string? Value
    {
        get => _value;
        set
        {
            _log($"VM.set_Value is called with: {value}");
            if (_value != value)
            {
                _value = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value)));
            }
        }
    }
}

The outcome on WinUI:

image

And on Uno WPF:

image


With PUSH_FROM_VM_TO_CONTROL:

WinUI:

image

Uno WPF:

image

For this case, there is an unimportant behavior mismatch that the setter is called twice on WinUI but once with Uno. But that shouldn't be a problem as usually the property will do nothing if its backing field is the same as the coming value (otherwise it should stackoverflow in WinUI anyways)


So, with the above repro, I can't see that subscriptions should die after unloading.

UnoApp14.zip

@jeromelaban
Copy link
Member Author

Related pr: #16631

@Youssef1313 Youssef1313 removed their assignment May 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/xBind 🪢 Categorizes an issue or PR as relevant to x:Bind difficulty/tbd Categorizes an issue for which the difficulty level needs to be defined. kind/bug Something isn't working triage/untriaged Indicates an issue requires triaging or verification
Projects
None yet
Development

No branches or pull requests

2 participants