CsWinRT 3 seems to not add ICustomPropertyProvider to all CCWs under the assumption that XAML will fallback to using Application's IXamlMetadataProvider implementation for binding properties,
But XAML won't actually use any type from the metadata provider as a binding source unless its corresponding IXamlType implementation returns true for IXamlType.IsBindable which is only the case if the type is annotated with [Bindable] attribute.
So there is still a need to have ICustomPropertyProvider automatically added to all CCWs.
This change would require changing [GeneratedCustomPropertyProvider] to generate an implementation for IBindableCustomPropertyImplementation rather than for ICustomPropertyProvider, so basically CsWinRT 2' behavior
the default implementation for ICustomPropertyProvider can use the same behavior of ManagedCustomPropertyProviderVftbl from CsWinRT 2, but an additional IXamlMetadataProvider-based fallback might be needed for non-JIT/NAOT scenarios, example implementation of such fallback (might need some tweaks for CsWinRT 3):
// inside ICustomPropertyProvider.GetCustomProperty impl
var provider = (IXamlMetadataProvider)Application.Current; // probably needs to be invoked through UnsafeAccessor to support both WUX and MUX
if (provider.GetXamlType(target.GetType()) is IXamlType xamlType)
{
if (xamlType.GetMember(_name) is IXamlMember xamlMember)
{
var metadataCustomProperty = new MetadataCustomProperty(xamlMember);
*result = MarshalInterface<ICustomProperty>.FromManaged(metadataCustomProperty);
return 0;
}
}
...
[WinRTExposedType(typeof(CustomPropertyWinRTTypeDetails))]
internal sealed class MetadataCustomProperty : ICustomProperty
{
private readonly IXamlMember _property;
public MetadataCustomProperty(IXamlMember propertyMember)
{
_property = propertyMember;
}
public bool CanRead => true;
public bool CanWrite => !_property.IsReadOnly;
public string Name => _property.Name;
public Type Type => _property.Type.UnderlyingType;
[DoesNotReturn]
public object GetIndexedValue(object target, object index)
{
throw new NotSupportedException();
}
public object GetValue(object target)
{
return _property.GetValue(target);
}
[DoesNotReturn]
public void SetIndexedValue(object target, object value, object index)
{
throw new NotSupportedException();
}
public void SetValue(object target, object value)
{
_property.SetValue(target, value);
}
}
CsWinRT 3 seems to not add
ICustomPropertyProviderto all CCWs under the assumption that XAML will fallback to using Application'sIXamlMetadataProviderimplementation for binding properties,But XAML won't actually use any type from the metadata provider as a binding source unless its corresponding
IXamlTypeimplementation returnstrueforIXamlType.IsBindablewhich is only the case if the type is annotated with[Bindable]attribute.So there is still a need to have
ICustomPropertyProviderautomatically added to all CCWs.This change would require changing
[GeneratedCustomPropertyProvider]to generate an implementation forIBindableCustomPropertyImplementationrather than forICustomPropertyProvider, so basically CsWinRT 2' behaviorthe default implementation for
ICustomPropertyProvidercan use the same behavior ofManagedCustomPropertyProviderVftblfrom CsWinRT 2, but an additionalIXamlMetadataProvider-based fallback might be needed for non-JIT/NAOT scenarios, example implementation of such fallback (might need some tweaks for CsWinRT 3):