Description
Summary
The Microsoft.Maui.Controls.SourceGen XAML generator in MAUI 11.0.0-preview.5.26304.4
(and the earlier 11.0.0-preview.4.26230.3) does not implement step 4 of the
name‑resolution precedence defined in the
XamlCSharpExpressions
spec. When the leading identifier in an expression matches no BindingContext
member and no code‑behind member, the generator should treat it as a static type
reference. Today it instead emits ((TDataType)BindingContext).<Identifier>, which
fails with CS1061 at compile time.
Affected types
Confirmed for at least:
Colors (from Microsoft.Maui.Graphics, imported via global using in MAUI)
DateTime (from System)
Math (from System)
Likely affects every other static type (e.g. Math, String, Convert, user
static classes, MyApp.AppConstants, etc.).
Repro
Project: net11.0-windows10.0.19041.0, Microsoft.Maui.Controls
11.0.0-preview.5.26304.4, MauiXamlInflator=SourceGen,
MauiXamlHotReload=SourceGen. Also reproduced on 11.0.0-preview.4.26230.3.
Built with .NET SDK 11.0.100-preview.4.26230.115 (MAUI workload manifest
11.0.0-preview.4.26230.3); the source generator under test comes from the
preview.5 Microsoft.Maui.Controls NuGet package.
MainPage.xaml (x:DataType="local:MainViewModel"):
<!-- Ternary that picks one of two static color members -->
<Label TextColor="{IsVip ? Colors.Goldenrod : Colors.Gray}" />
<!-- Static property in an interpolation hole -->
<Label Text="{$'Now: {DateTime.Now:t}'}" />
<!-- Static method call with bound arguments -->
<Label Text="{$'Max = {Math.Max(Price, Quantity):F2}'}" />
<!-- Mixed: bound member + static property -->
<Label Text="{$'{Name} - {DateTime.Now:d}'}" />
MainViewModel defines IsVip, Name, Price, Quantity only.
Actual
Five errors, all of the same shape:
error CS1061: 'MainViewModel' does not contain a definition for 'Colors' …
error CS1061: 'MainViewModel' does not contain a definition for 'DateTime' …
error CS1061: 'MainViewModel' does not contain a definition for 'Math' …
i.e. the generator produced (decompiled equivalent):
((MainViewModel)BindingContext).Colors.Goldenrod // wrong
((MainViewModel)BindingContext).DateTime.Now // wrong
((MainViewModel)BindingContext).Math.Max(...) // wrong
Expected (per spec)
The spec (XamlCSharpExpressions.md)
lists name‑resolution order as:
- Local lambda parameters (
s, e, …)
- Members of
x:DataType (BindingContext)
- Members of the code‑behind class (
this)
- Static types reachable via the file's imports /
global using set
Because Colors, DateTime, Math resolve neither at step 2 nor step 3, the
generator should fall through to step 4 and emit:
global::Microsoft.Maui.Graphics.Colors.Goldenrod
global::System.DateTime.Now
global::System.Math.Max((double)((MainViewModel)BindingContext).Price,
(double)((MainViewModel)BindingContext).Quantity)
The Syncfusion blog (
https://www.syncfusion.com/blogs/post/csharp-expressions-xaml-dotnet11-maui ),
which is based on the same spec, advertises exactly these forms as working in
.NET 11 preview.
Things that DO work in this build (for completeness)
The same project compiles fine with:
{Name} / {= Name} / {.Name} / {this.PageTitle}
{$'Hello, {Name}!'}, {$'{Price:C2}'}, {$'{Price * Quantity:C2}'}
{!IsHidden}, {HasAccount && AgreedToTerms}, {IsAdmin || IsPrivileged}
{Status ?? 'Unknown'}
{IsVip ? 'Gold tier' : 'Standard tier'} (string ternary)
{Quantity > MinimumCount}, {Quantity GT MinimumCount},
{Quantity GTE 1 AND Quantity LTE 10}
{User.DisplayName} (nested path, two‑way)
Clicked="{(s, e) => this.OnCounterClicked()}" and
Clicked="{(s, e) => ((MainViewModel)BindingContext).ClickCount++}"
<![CDATA[{Quantity > 0 && Quantity < 100}]]> in element syntax
So the failure is specifically isolated to step 4 of the precedence rule.
Steps to Reproduce
See the test application here: https://github.com/noiseonwires/MauiXamlCsharpSample/tree/more_expressions (more_expressions branch)
Link to public reproduction project repository
https://github.com/noiseonwires/MauiXamlCsharpSample/tree/more_expressions
Version with bug
11.0.0-preview.4
Is this a regression from previous behavior?
Not sure, did not test other versions
Last version that worked well
No response
Affected platforms
I was not able test on other platforms
Affected platform versions
No response
Did you find any workaround?
(all undesirable):
- Add a wrapper instance member on the code‑behind / VM that returns the static
value (public string Now => $"Now: {DateTime.Now:t}";). Defeats the entire
purpose of the new expression syntax.
- Add a fully‑qualified
xmlns:sys="clr-namespace:System;assembly=…" and use
{x:Static sys:DateTime.Now} (old syntax).
Relevant log output
C:\src\MauiXamlCsharpSample\obj\Debug\net11.0-maccatalyst\maccatalyst-x64\Microsoft.Maui.Controls.SourceGen\Microsoft.Maui.Controls.SourceGen.XamlGenerator\MainPage.xaml.xsg.cs(882,38): error CS1061: 'MainViewModel' does not contain a definition for 'Colors' and no accessible extension method 'Colors' accepting a first argument of type 'MainViewModel' could be found (are you missing a using directive or an assembly reference?)
C:\src\MauiXamlCsharpSample\obj\Debug\net11.0-maccatalyst\maccatalyst-x64\Microsoft.Maui.Controls.SourceGen\Microsoft.Maui.Controls.SourceGen.XamlGenerator\MainPage.xaml.xsg.cs(1097,38): error CS1061: 'MainViewModel' does not contain a definition for 'DateTime' and no accessible extension method 'DateTime' accepting a first argument of type 'MainViewModel' could be found (are you missing a using directive or an assembly reference?)
C:\src\MauiXamlCsharpSample\obj\Debug\net11.0-maccatalyst\maccatalyst-x64\Microsoft.Maui.Controls.SourceGen\Microsoft.Maui.Controls.SourceGen.XamlGenerator\MainPage.xaml.xsg.cs(1106,38): error CS1061: 'MainViewModel' does not contain a definition for 'Math' and no accessible extension method 'Math' accepting a first argument of type 'MainViewModel' could be found (are you missing a using directive or an assembly reference?)
Description
Summary
The
Microsoft.Maui.Controls.SourceGenXAML generator in MAUI 11.0.0-preview.5.26304.4(and the earlier 11.0.0-preview.4.26230.3) does not implement step 4 of the
name‑resolution precedence defined in the
XamlCSharpExpressions
spec. When the leading identifier in an expression matches no
BindingContextmember and no code‑behind member, the generator should treat it as a static type
reference. Today it instead emits
((TDataType)BindingContext).<Identifier>, whichfails with
CS1061at compile time.Affected types
Confirmed for at least:
Colors(fromMicrosoft.Maui.Graphics, imported viaglobal usingin MAUI)DateTime(fromSystem)Math(fromSystem)Likely affects every other static type (e.g.
Math,String,Convert, userstatic classes,
MyApp.AppConstants, etc.).Repro
Project: net11.0-windows10.0.19041.0,
Microsoft.Maui.Controls11.0.0-preview.5.26304.4,MauiXamlInflator=SourceGen,MauiXamlHotReload=SourceGen. Also reproduced on11.0.0-preview.4.26230.3.Built with .NET SDK
11.0.100-preview.4.26230.115(MAUI workload manifest11.0.0-preview.4.26230.3); the source generator under test comes from thepreview.5
Microsoft.Maui.ControlsNuGet package.MainPage.xaml(x:DataType="local:MainViewModel"):MainViewModeldefinesIsVip,Name,Price,Quantityonly.Actual
Five errors, all of the same shape:
i.e. the generator produced (decompiled equivalent):
Expected (per spec)
The spec (XamlCSharpExpressions.md)
lists name‑resolution order as:
s,e, …)x:DataType(BindingContext)this)global usingsetBecause
Colors,DateTime,Mathresolve neither at step 2 nor step 3, thegenerator should fall through to step 4 and emit:
The Syncfusion blog (
https://www.syncfusion.com/blogs/post/csharp-expressions-xaml-dotnet11-maui ),
which is based on the same spec, advertises exactly these forms as working in
.NET 11 preview.
Things that DO work in this build (for completeness)
The same project compiles fine with:
{Name}/{= Name}/{.Name}/{this.PageTitle}{$'Hello, {Name}!'},{$'{Price:C2}'},{$'{Price * Quantity:C2}'}{!IsHidden},{HasAccount && AgreedToTerms},{IsAdmin || IsPrivileged}{Status ?? 'Unknown'}{IsVip ? 'Gold tier' : 'Standard tier'}(string ternary){Quantity > MinimumCount},{Quantity GT MinimumCount},{Quantity GTE 1 AND Quantity LTE 10}{User.DisplayName}(nested path, two‑way)Clicked="{(s, e) => this.OnCounterClicked()}"andClicked="{(s, e) => ((MainViewModel)BindingContext).ClickCount++}"<![CDATA[{Quantity > 0 && Quantity < 100}]]>in element syntaxSo the failure is specifically isolated to step 4 of the precedence rule.
Steps to Reproduce
See the test application here: https://github.com/noiseonwires/MauiXamlCsharpSample/tree/more_expressions (
more_expressionsbranch)Link to public reproduction project repository
https://github.com/noiseonwires/MauiXamlCsharpSample/tree/more_expressions
Version with bug
11.0.0-preview.4
Is this a regression from previous behavior?
Not sure, did not test other versions
Last version that worked well
No response
Affected platforms
I was not able test on other platforms
Affected platform versions
No response
Did you find any workaround?
(all undesirable):
value (
public string Now => $"Now: {DateTime.Now:t}";). Defeats the entirepurpose of the new expression syntax.
xmlns:sys="clr-namespace:System;assembly=…"and use{x:Static sys:DateTime.Now}(old syntax).Relevant log output