[CsWinRT 3] ICustomPropertyProvider is not added to all CCWs
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 665
- Forks
- 134
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 32
Description
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);
}
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing the [GeneratedCustomPropertyProvider] implementation and the ManagedCustomPropertyProviderVftbl behavior described for CsWinRT 2. Check how ICustomPropertyProvider and IBindableCustomPropertyImplementation are exposed to CCWs, including the IXamlMetadataProvider fallback. Done means all relevant CCWs expose ICustomPropertyProvider and XAML binding works for types that are not annotated with [Bindable].
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100