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

Callback for RegisterPropertyChangedCallback is fired when a child is added and it inherits a property whereas it's not in WinUI #15437

Open
Youssef1313 opened this issue Feb 12, 2024 · 3 comments
Labels
difficulty/tbd Categorizes an issue for which the difficulty level needs to be defined. kind/bug Something isn't working project/core-tools 🛠️ Categorizes an issue or PR as relevant to core and tools

Comments

@Youssef1313
Copy link
Member

Current behavior

			var sp = new StackPanel()
			{
				Background = new SolidColorBrush(Colors.Red),
				XYFocusKeyboardNavigation = Microsoft.UI.Xaml.Input.XYFocusKeyboardNavigationMode.Disabled,
				FlowDirection = FlowDirection.RightToLeft,
			};

			var tb = new TextBlock();
			tb.RegisterPropertyChangedCallback(UIElement.XYFocusKeyboardNavigationProperty, (_, _) =>
			{
				sp.Children.Clear();
				sp.Children.Add(new Border());
			});

			tb.RegisterPropertyChangedCallback(FrameworkElement.FlowDirectionProperty, (_, _) =>
			{
				sp.Children.Clear();
				sp.Children.Add(new Border());
			});

			sp.Children.Add(tb);

This test code fires both callbacks. On WinUI, none is fired.

Expected behavior

No response

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)

No response

Affected platforms

No response

IDE

No response

IDE version

No response

Relevant plugins

No response

Anything else we need to know?

No response

@Youssef1313 Youssef1313 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 Feb 12, 2024
@jeromelaban jeromelaban added project/core-tools 🛠️ Categorizes an issue or PR as relevant to core and tools and removed triage/untriaged Indicates an issue requires triaging or verification labels Feb 13, 2024
@Youssef1313 Youssef1313 self-assigned this Feb 20, 2024
@Youssef1313
Copy link
Member Author

Fixing this isn't as easy as it may look. The binding engine relies on RegisterPropertyChangedCallback, and fixing this issue will break the binding engine.

@Youssef1313 Youssef1313 removed their assignment Feb 20, 2024
@Youssef1313
Copy link
Member Author

NOTE: In WinUI, x:Bind uses RegisterPropertyChangedCallback. So, for the following code:

    <StackPanel>
        <Button Content="Click me" Click="Button_Click" />
        <TextBlock x:Name="tb">
            <Run Text="Hello1" x:Name="hello1" />
            <Run Text="Hello2" Foreground="Red" />
            <Run Text="Hello2" Foreground="{x:Bind hello1.Foreground, Mode=OneWay}" />
        </TextBlock>
    </StackPanel>
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            tb.Foreground = new SolidColorBrush(Colors.Green);
        }

It initially renders as follows:

image

Then, once the button is clicked, it becomes:

image

@Youssef1313
Copy link
Member Author

Youssef1313 commented Apr 9, 2024

Another scenario not aligning with my hypothesis:

    <StackPanel x:Name="sp">
        <Button Content="Click me" Click="Button_Click" />
        <TextBlock x:Name="tb1" Text="Inherited normally" />
        <TextBlock x:Name="tb2" Text="Bound using x:Bind" FlowDirection="{x:Bind tb1.FlowDirection, Mode=OneWay}" />
        <TextBlock x:Name="tb3" Text="Bound using Binding" FlowDirection="{Binding FlowDirection, Mode=OneWay}" />
    </StackPanel>
        public MainWindow()
        {
            this.InitializeComponent();
            tb3.DataContext = tb1;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            sp.FlowDirection = FlowDirection.RightToLeft;
        }

Before click:

image

After click:

image

Callstack when x:Bind was notified of the inherited property change:

image

**The key difference is that in the first scenario, the children are Runs (not UIElements). It seems that inheritance is only propagated to Children UIElements. We need to validate whether Uno behaves the same or not (I have not yet)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
difficulty/tbd Categorizes an issue for which the difficulty level needs to be defined. kind/bug Something isn't working project/core-tools 🛠️ Categorizes an issue or PR as relevant to core and tools
Projects
None yet
Development

No branches or pull requests

2 participants