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

Epic: Add new SetBinding API for defining "compiled" bindings in code #22384

Closed
21 of 26 tasks
simonrozsival opened this issue May 14, 2024 · 3 comments
Closed
21 of 26 tasks
Assignees
Labels
area-xaml XAML, CSS, Triggers, Behaviors Epic Groups multiple user stories. Can be grouped under a theme.
Milestone

Comments

@simonrozsival
Copy link
Member

simonrozsival commented May 14, 2024

We agreed to implement a new public API to allow creating "compiled" bindings (TypedBinding<TSource, TProperty>) in code via source-generators and interceptors based on the proposal #20574 (see Alternative design).

  • Introduce new public method BindableObjectExtensions.SetBinding<TSource, TProperty>(BindableProperty property, Func<TSource, TProperty> getter, ...) as defined in the proposal
  • Create a new source generator
    • Intercept calls to SetBinding<TSource, TProperty>(...)
    • Parse getter lambda expression
      • Implement support for properties
      • Implement support for indexers
      • Implement support for as-casts
      • Implement support for C-style casts
      • Implement support for conditional access to members
      • Implement diagnostics reporting
      • Build cacheable data model
    • Generate setter from the getter lambda
    • Generate handlers array from the getter lambda
  • Enable the source generator by default in MAUI apps
    • Introduce a feature switch to disable the source generator
  • Add unit tests for correct caching of the generated code
  • Run benchmarks comparing reflection-based binding, source-generated binding, and hand-written typed binding
  • Write docs/developer guide - tracked in .NET MAUI 9: Compiled bindings can be used with C# markup docs-maui#2304

Possible future improvements

@simonrozsival simonrozsival added area-xaml XAML, CSS, Triggers, Behaviors Epic Groups multiple user stories. Can be grouped under a theme. labels May 14, 2024
@simonrozsival simonrozsival added this to the .NET 9 Planning milestone May 14, 2024
Copy link
Contributor

Hi I'm an AI powered bot that finds similar issues based off the issue title.

Please view the issues below to see if they solve your problem, and if the issue describes your problem please consider closing this one and thumbs upping the other issue to help us prioritize it. Thank you!

Open similar issues:

Note: You can give me feedback by thumbs upping or thumbs downing this comment.

@AmrAlSayed0
Copy link
Contributor

In this proposal #20574, the generated method StudentFirstNameBinding could benefit from being generic. So instead of this

partial class StudentDetailPage
{
    private static BindingBase StudentFirstNameBinding(
        object? source = null,
        BindingMode mode = BindingMode.OneWay, // default value based on the attribute value
        IValueConverter? converter = null,
        object? converterParameter = null,
        string? stringFormat = null,
        object? targetNullValue = null,
        object? fallbackValue = null)
        => ...;
}

it would be this

partial class StudentDetailPage
{
    private static BindingBase StudentFirstNameBinding<TSource, TProperty>(
        TSource? source = null,
        BindingMode mode = BindingMode.OneWay, // default value based on the attribute value
        IValueConverter? converter = null,
        object? converterParameter = null,
        [System.Diagnostics.CodeAnalysis.StringSyntax] string? stringFormat = null,
        TProperty? targetNullValue = null,
        TProperty? fallbackValue = null)
        => ...;
}

Same thing with SetBinding

public static partial class BindableObjectExtensions
{
    public static void SetBinding<TSource, TProperty>(
        this TSource self,
        BindableProperty property,
        Func<TSource, TProperty> getter,
        Action<TSource, TProperty>? setter = null,
	BindingMode mode = BindingMode.Default,
	IValueConverter? converter = null,
	object? converterParameter = null,
	[System.Diagnostics.CodeAnalysis.StringSyntax] string? stringFormat = null,
	object? source = null,
	TProperty? fallbackValue = null,
	TProperty? targetNullValue = null) where TSource : BindableObject
    {
        throw new InvalidOperationException($"The method call to {nameof(SetBinding<TSource, TProperty>)} was not intercepted.");
    }
}

Also, would it be useful to think about introducing a generic IValueConverter<TFrom, TTo> or even IValueConverter<TFrom, TTo, TParameter>? I know that converters are often used to convert from multiple value types but if there is a use case that only needs to convert from one type then this allows more types to flow through the linker's analysis and hopefully not trim out the types. I don't think that following the outdated Interface of the WPF days is useful here.

Finally, keep up the good work 💪

@PureWeen PureWeen modified the milestones: 9.0-preview6, 9.0-rc1 Aug 2, 2024
@PureWeen PureWeen modified the milestones: 9.0-rc1, 9.0-rc2 Aug 23, 2024
@simonrozsival
Copy link
Member Author

This new API has been released and is part of .NET MAUI 9 RC 1.

@github-actions github-actions bot locked and limited conversation to collaborators Oct 20, 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 Epic Groups multiple user stories. Can be grouped under a theme.
Projects
Status: Done
Development

No branches or pull requests

4 participants