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

Improve the usage experience with CompareConverter in XAML #1841

Merged
merged 6 commits into from
Apr 29, 2024

Conversation

bijington
Copy link
Contributor

@bijington bijington commented Apr 28, 2024

Description of Change

The aim of this PR is to simplify the usage of the CompareConverter through better control of implementation when inheriting form CompareConverter.

The current usage of the converter is as follows:

<x:Double x:Key="ComparingValue">0.5</x:Double>
<Color x:Key="LightGreen">LightGreen</Color>
<Color x:Key="PaleVioletRed">PaleVioletRed</Color>
            
<converters:CompareDoubleToColorConverter
    x:Key="isLargerThanOneConverter"
    ComparingValue="{StaticResource ComparingValue}"
    ComparisonOperator="Greater"
    TrueObject="{StaticResource LightGreen}"
    FalseObject="{StaticResource PaleVioletRed}" />

If a developer tries to write ComparingValue="0.5" they will receive a compilation error stating:

No property, BindableProperty, or event found for "ComparingValue", or mismatching type between value and property

This is down to the fact that ComparingValue is of type IComparable and there is no implicit conversion that can be determined between the value 0.5 (which is a string) to IComparable.

This PR makes it possible to define what type ComparingValue should be when inheriting from the converter. Therefore usage becomes:

Converter definition

public sealed class CompareDoubleToColorConverter : CompareConverter<double, Color>
{
}

XAML usage

<converters:CompareDoubleToColorConverter
    x:Key="isLargerThanOneConverter"
    ComparingValue="1"
    ComparisonOperator="Greater"
    TrueObject="LightGreen"
    FalseObject="PaleVioletRed" />

It might feel like a small improvement but I believe it will make quite a difference, especially when using the markup extension to define it inside the binding. The definitions become a lot more concise.

Question

Should we go a step further and make ComparingValue a BindableProperty and allow developers to make the value dynamic through the use of bindings? I think yes but I would like to see what others think.

Linked Issues

PR Checklist

Additional information

@brminnick
Copy link
Collaborator

I like it! Should we update the docs to demonstrate this as the recommended way going forward to use CompareConverter?

@bijington
Copy link
Contributor Author

Yes I'll update the docs to reflect this 👍

@brminnick brminnick added pending documentation This feature requires documentation approved This Proposal has been approved and is ready to be added to the Toolkit labels Apr 29, 2024
@brminnick
Copy link
Collaborator

Right on! I've added the approved This Proposal has been approved and is ready to be added to the Toolkit and pending documentation This feature requires documentation labels for now.

It looks like there's a missing XML comment somewhere causing the build to fail, but once that's fixed (and the docs are generated) I'm happy to approve + merge 🙌

@bijington
Copy link
Contributor Author

Awesome thanks @brminnick. Technically this change is breaking because CompareConverter now takes 2 type arguments.

It went from

public abstract class CompareConverter<TReturnObject> : BaseConverterOneWay<IComparable, object>

to

public abstract class CompareConverter<TValue, TReturnObject> : BaseConverterOneWay<TValue, object> where TValue : IComparable

If we want to avoid a major version now and breaking developers straightaway we could add in the following and mark it as [Obsolete]

[Obsolete]
public abstract class CompareConverter<TReturnObject> : CompareConverter <IComparable, TReturnObject>

This would provide a more gentle break for those that are already using CompareConverter and not having an issue. What do you think?

@brminnick brminnick added the breaking change This label is used for PRs that include a breaking change label Apr 29, 2024
@brminnick
Copy link
Collaborator

Good catch! I've added the breaking change This label is used for PRs that include a breaking change label too.

Nah, don't worry about it. We recently merged another breaking change in #1839, so our next release will be a major version bump anyways.

We'll both just want to double check the Release Notes to ensure these PRs with the breaking change This label is used for PRs that include a breaking change are called out 💯

@brminnick brminnick enabled auto-merge (squash) April 29, 2024 19:04
@brminnick brminnick merged commit bcd463e into main Apr 29, 2024
7 checks passed
@brminnick brminnick deleted the feature/sl-1437 branch April 29, 2024 19:20
@bijington
Copy link
Contributor Author

Docs are at: MicrosoftDocs/CommunityToolkit#415

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved This Proposal has been approved and is ready to be added to the Toolkit breaking change This label is used for PRs that include a breaking change pending documentation This feature requires documentation
Projects
None yet
2 participants