-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Compile-time binding of BindingContext should use the inherited x:DataType #21434
Comments
Verified this issue with Visual Studio 17.10 preview2 (8.0.14 &8.0.3). Can repro on Android platform with sample project(Compiled bindings (2)). |
Hello @jskeet! Thanks for reporting this issue. I can repro this issue also on the current The workaround you found works because in .NET 8, XamlC can't compile bindings with relative source. The binding will be a dynamic binding and not a compiled binding. This should change in .NET 9 and this workaround wouldn't work anymore. You should probably use this code instead: <VerticalStackLayout>
<Label Text="{Binding Text}" />
<Label BindingContext="{Binding Child, x:DataType=local:ParentViewModel}" Text="{Binding Text}" x:DataType="local:ChildViewModel" />
<!-- also works: -->
<Label BindingContext="{Binding Child}" Text="{Binding Text2, x:DataType=local:ChildViewModel}" />
</VerticalStackLayout> @StephaneDelcroix Is this the indended behavior of XamlC? It seems like a bug. |
@simonrozsival: Thanks for the extra information, that's really useful. I'd looked for a way of specifying a DataType just for the binding, but had missed it. Sounds like that's a better fix - I'll apply it to my real project tonight. Presumably if I'm binding to multiple properties (and don't want to repeat the ChildViewModel data type) I could use that in the binding for the BindingContext instead, and use <Label BindingContext="{Binding Child, x:DataType=local:ParentViewModel}"
x:DataType="local:ChildViewModel"
Text="{Binding Text2}"
Visible="{Binding AnotherPropertyInChildViewModel}"
/> Of course, in an ideal world I wouldn't need to specify the data type at all for the label - if |
Yes, exactly.
That would certainly be great but I'm afraid that's outside of the scope at the moment. @StephaneDelcroix might know more details about future plans. |
@simonrozsival: I've just tried specifying the DataType in the binding: <Label BindingContext="{Binding Child}"
Text="{Binding Text2, x:DataType=local:ChildViewModel}"/> This leads to an error:
I'm currently using .NET 8 - is that something that you'd only expect to work in .NET 9? (If so, I'll stick with the dynamic binding as per my original workaround.) Apologies if I've missed some other change required to make this work. |
@jskeet I tested it on the .NET 9 branch, so it is possible that this doesn't work in .NET 8 (although I was convinced it would work). I will try to test with .NET 8 later today and I will let you know. |
@jskeet It should work with .NET 8. @PureWeen @mattleibow the |
Thanks, will try a command line build. The error comes in latest stable VS - can give precise versions when I'm back at my desk if that's useful. |
Ah - my mistake, it wasn't a build error, but a VS error that only shows up when the XAML file is in an editor. |
Description
Consider a XAML element which specifies both a
BindingContext
that uses a binding from its inheritedBindingContext
, and another dependency property using aBinding
:x:DataType
on the element, both bindings are compiled as if they refer to the inherited binding context data typex:DataType
on the element, both bindings are compiled as if they refer to the newly-specified typeWhat you actually want is for the binding in
BindingContext
to be resolved against the inheritedBindingContext
data type, and all other bindings to be resolved against either the newly-specifiedx:DataType
or (better) against the compile-time type of the newBindingContext
.Steps to Reproduce
ContextAndType
(or adjust theclr-namespace
in the examples to match whatever you choose)ParentViewModel.cs
file containing:Now we can experiment...
Dynamic bindings
Edit MainPage.xaml to:
Note that this has no
x:DataType
specified, so the bindings are dynamic.Run the code (I ran it on my local Android device, in the debugger, as well as on my Windows box - I don't know if Debug/Release makes any difference).
Result: Labels of "ParentText" then "ChildText"
In other words, the bindings are behaving as I'd expect:
Label
hasText
bound toParentViewModel.Text
Label
hasBindingContext
is bound toParentViewModel.Child
Label
hasText
bound toChildViewModel.Text
There are three warnings of "Binding could be compiled if x:DataType is specified."
Compiled bindings (1)
Just add
x:DataType
oflocal:ParentViewModel
to the root element:This still compiles, and runs with the same output. (Note that the
Text
property exists in bothParentViewModel
andChildViewModel
, which is - I believe - why it compiles. Given what comes later though, I'm surprised it doesn't fail at execution time.)Compiled bindings (2)
Change the second label to use the
Text2
property:Result: Compile-time failure:
Compiled bindings (3)
Okay, let's be clear and specify that the type of the
BindingContext
for the second label is expected to beChildViewModel
, by addingx:DataType
to it:Result: Compile-time failure:
Compiled bindings (4)
I've found a workaround: specify the source of the
BindingContext
Binding
:Result: Labels of "ParentText" then "ChildText2".
So this works - but it feels clunky to have to specify it.
Link to public reproduction project repository
https://github.com/jskeet/DemoCode/tree/main/MauiBugDemos/ContextAndType
Version with bug
8.0.7 SR2
Is this a regression from previous behavior?
Not sure, did not test other versions
Last version that worked well
Unknown/Other
Affected platforms
Android, Windows, I was not able test on other platforms
Affected platform versions
No response
Did you find any workaround?
Relevant log output
No response
The text was updated successfully, but these errors were encountered: