Skip to content

XAML C# Expressions source generator does not resolve bare static type names per spec #35900

Description

@noiseonwires

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:

  1. Local lambda parameters (s, e, …)
  2. Members of x:DataType (BindingContext)
  3. Members of the code‑behind class (this)
  4. 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?)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions