Unfortunately implementation of IProvideValueTarget.TargetProperty
property is missing in Xamarin.Forms.
The implementation of property looks like this:
public object TargetProperty
{
get { throw new NotImplementedException(); }
private set { }
}
It's not very convenient for writing custom MarkupExtensions without this property. I use this workaround to get property name:
For Xamarin.Forms < 1.4:
public static class Ext
{
public static PropertyInfo GetPropertyEx(this Type type, string name)
{
while (type != null)
{
var typeInfo = type.GetTypeInfo();
var p = typeInfo.GetDeclaredProperty(name);
if (p != null)
return p;
type = typeInfo.BaseType;
}
return null;
}
}
var property = serviceProvider.GetType().GetPropertyEx("IXamlNodeProvider");
var xamlNodeProvider = property.GetValue(serviceProvider);
property = xamlNodeProvider.GetType().GetPropertyEx("XamlNode");
var xamlNode = property.GetValue(xamlNodeProvider);
property = xamlNode.GetType().GetPropertyEx("Parent");
var parentNode = property.GetValue(xamlNode);
property = parentNode.GetType().GetPropertyEx("Properties");
var properties = (IDictionary)property.GetValue(parentNode);
object xmlName = null;
foreach (DictionaryEntry entry in properties)
{
if (ReferenceEquals(entry.Value, xamlNode))
{
xmlName = entry.Key;
break;
}
}
property = xmlName.GetType().GetPropertyEx("LocalName");
var propertyName = (string)property.GetValue(xmlName);
var target = ((IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget))).TargetObject;
var targetProperty = target.GetType().GetPropertyEx(propertyName);
For Xamarin.Forms >= 1.4:
var provideValueTarget = (IProvideValueTarget) serviceProvider.GetService(typeof (IProvideValueTarget));
var property = provideValueTarget.GetType().GetPropertyEx("Node");
var xamlNode = property.GetValue(provideValueTarget);
property = xamlNode.GetType().GetPropertyEx("Parent");
var parentNode = property.GetValue(xamlNode);
property = parentNode.GetType().GetPropertyEx("Properties");
var properties = (IDictionary)property.GetValue(parentNode);
object xmlName = null;
foreach (DictionaryEntry entry in properties)
{
if (ReferenceEquals(entry.Value, xamlNode))
{
xmlName = entry.Key;
break;
}
}
property = xmlName.GetType().GetPropertyEx("LocalName");
var propertyName = (string)property.GetValue(xmlName);
var target = provideValueTarget.TargetObject;
var targetProperty = target.GetType().GetPropertyEx(propertyName);
Dear Xamarin.Forms team please add the implementation of this property, this should not be a problem.
Regards