BindableProperty should accept generics #16302
Unanswered
symbiogenesis
asked this question in
Ideas
Replies: 2 comments 1 reply
-
This approach works: using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using Microsoft.Maui.Controls;
using static Microsoft.Maui.Controls.BindableProperty;
internal static class BindablePropertyExtensions
{
public static BindableProperty Create<TDeclaringType, TReturnType>(string propertyName, TReturnType defaultValue = default, BindingMode defaultBindingMode = BindingMode.OneWay, ValidateValueDelegate<TReturnType> validateValue = null,
BindingPropertyChangedDelegate<TReturnType> propertyChanged = null, BindingPropertyChangingDelegate<TReturnType> propertyChanging = null, CoerceValueDelegate<TReturnType> coerceValue = null,
CreateDefaultValueDelegate<TDeclaringType, TReturnType> defaultValueCreator = null)
{
ValidateValueDelegate untypedValidateValue = null;
if (validateValue != null)
{
untypedValidateValue = (bindable, value) => validateValue(bindable, value is TReturnType typedValue ? typedValue : default);
}
BindingPropertyChangedDelegate untypedPropertyChanged = null;
if (propertyChanged != null)
{
untypedPropertyChanged = (bindable, o, n) => propertyChanged(bindable, o is TReturnType typedOldValue ? typedOldValue : default, n is TReturnType typedNewValue ? typedNewValue : default);
}
BindingPropertyChangingDelegate untypedPropertyChanging = null;
if (propertyChanging != null)
{
untypedPropertyChanging = (bindable, o, n) => propertyChanging(bindable, o is TReturnType typedOldValue ? typedOldValue : default, n is TReturnType typedNewValue ? typedNewValue : default);
}
CoerceValueDelegate untypedCoerceValue = null;
if (coerceValue != null)
{
untypedCoerceValue = (bindable, value) => coerceValue(bindable, value is TReturnType typedValue ? typedValue : default);
}
CreateDefaultValueDelegate untypedDefaultValueCreator = null;
if (defaultValueCreator != null)
{
untypedDefaultValueCreator = (bindable) => defaultValueCreator(bindable is TDeclaringType typedBindable ? typedBindable : default);
}
return BindableProperty.Create(propertyName, typeof(TReturnType), typeof(TDeclaringType), defaultValue, defaultBindingMode, untypedValidateValue, untypedPropertyChanged, untypedPropertyChanging, untypedCoerceValue, untypedDefaultValueCreator);
}
} |
Beta Was this translation helpful? Give feedback.
0 replies
-
@symbiogenesis Hi, I'd like to use the same approach. Would you mind sharing how to use the Create method and how to set the BindingProperty in XAML? I'm getting compiler errors in the TReturnType parameter. Thanks in advance |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
BindableProperty is difficult to use. It generally involves doing a lot of casting and redundant boilerplate. I have a project with dozens of BindableProperties and each one is a pain to write and use.
For the Create() method, you have to pass in a Type, and yet despite having done so, you need to cast values within the various delegates. For instance, when you define the propertyChanged delegate, you have to cast both the oldValue and the newValue.
Additionally, BindableProperty is sealed, and thus I am not even able to extend it easily.
Beta Was this translation helpful? Give feedback.
All reactions