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

XAML Page Binding to Self Gets Incorrect Warning #25271

Closed
david-maw opened this issue Oct 14, 2024 · 5 comments
Closed

XAML Page Binding to Self Gets Incorrect Warning #25271

david-maw opened this issue Oct 14, 2024 · 5 comments
Labels
area-xaml XAML, CSS, Triggers, Behaviors i/regression This issue described a confirmed regression on a currently supported version platform/windows 🪟 s/triaged Issue has been reviewed s/verified Verified / Reproducible Issue ready for Engineering Triage t/bug Something isn't working

Comments

@david-maw
Copy link

Description

If a XAML page uses itself as a binding context it will get the following warning from the XAML compiler

Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information.

It gets this warning even if x:DataType is specified.

Steps to Reproduce

  1. Create a new MAUI App called SelfBinding
  2. Edit the project file to set MauiEnableXamlCBindingWithSourceCompilation
  3. Edit MainPage.xaml to add the following in the heading:
             xmlns:local="clr-namespace:SelfBinding"
             x:DataType="local:MainPage"
             BindingContext="{Binding Source={RelativeSource Self}}"

Then build it and observe the warning. At the very least it's not clear what it is suggesting.

Link to public reproduction project repository

https://github.com/david-maw/SelfBinding.git

Version with bug

9.0.0-rc.2.24503.2

Is this a regression from previous behavior?

No, this is something new

Last version that worked well

Unknown/Other

Affected platforms

Windows, I was not able test on other platforms

Affected platform versions

Windows 11 at compile time

Did you find any workaround?

No

Relevant log output

No response

@david-maw david-maw added the t/bug Something isn't working label Oct 14, 2024
@jsuarezruiz jsuarezruiz added the area-xaml XAML, CSS, Triggers, Behaviors label Oct 15, 2024
@ninachen03 ninachen03 added platform/windows 🪟 s/verified Verified / Reproducible Issue ready for Engineering Triage s/triaged Issue has been reviewed i/regression This issue described a confirmed regression on a currently supported version labels Oct 15, 2024
@ninachen03
Copy link

This issue has been verified using Visual Studio 17.12.0 Preview 2.1(9.0.0-rc.2.24503.2& 9.0.0-rc.1.24453.9). Can repro this issue on 9.0.0-rc.2.24503.2 and works fine on9.0.0-rc.1.24453.9
Image

@simonrozsival
Copy link
Member

Unfortunately, we can't infer the data type from Source yet (see #21834).

TL;DR add x:DataType to the {Binding} itself:

xmlns:local="clr-namespace:SelfBinding"
x:DataType="local:MainPage"
BindingContext="{Binding Source={RelativeSource Self}, x:DataType=local:MainPage}"

Longer answer: The x:DataType on an element specifies the type of the BindingContext. Therefore, it cannot usually be applied to the {Binding} that's assigned to the BindingContext property itself. Consider this scenario:

<A x:DataType="local:ViewModelA">
    <B x:DataType="local:ViewModelB" BindingContext="{Binding ViewModelB}" BackgroundColor="{Binding Color}">
        <!-- ... -->
    </B>
</A>
class ViewModelA
{
    public ViewModelB ViewModelB { get; set; }
}

class ViewModelB
{
    public Color Color { get; set; }
}

In this example, we set the binding context of B to ViewModelA.ViewModelB and the background color to ViewModelB.Color.

I see how this seems strange in your code where you're setting the BindingContext of the root element that cannot inherit any binding context. I'm not sure how common it is to set the binding context to self and if we should look for the cleaner solution that I described at the start of this comment.

@david-maw
Copy link
Author

Thanks @simonrozsival, that makes sense but leaves the problem that if I use:

BindingContext="{Binding Source={RelativeSource Self}}"

At the Page level I always get the warning Binding could be compiled to improve runtime performance if x:DataType is specified whether I specify an x:DataType at the page level or not.

The only workaround to eliminate the warning that I could come up with was to move the BindingContext initialization into code behind and just set BindingContext = this; in the constructor, which isn't terrible, since it's shorter and the x:DataType still in the XAML documents things adequately. I agree that a fix for #21834 would be better, but I want world peace too, and I'm not holding my breath for that either...

Does anyone have any other ideas, or shall I go ahead and just move the BindingContext initialization?

@simonrozsival
Copy link
Member

@david-maw you should be able to fix this by using the binding this way:

BindingContext="{Binding Source={RelativeSource Self}, x:DataType=local:MainPage}"

Setting the BindingContext in the constructor is going to be negligibly faster (there's no need to allocate the instance of the binding), but effectively equivalent.

Please feel free to close the issue if this solves the issue.

@david-maw
Copy link
Author

Thanks @simonrozsival, that works, no idea how I've gone this long without realizing you could embed an x:DataType in a XAML Binding specification.

@github-actions github-actions bot locked and limited conversation to collaborators Nov 16, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-xaml XAML, CSS, Triggers, Behaviors i/regression This issue described a confirmed regression on a currently supported version platform/windows 🪟 s/triaged Issue has been reviewed s/verified Verified / Reproducible Issue ready for Engineering Triage t/bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants