microsoft / microsoft/CsWinRT

[CsWinRT 3] ICustomPropertyProvider is not added to all CCWs

Open
#2,386 10 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

CsWinRT 3.0
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.