Is there a XAML equivalent to nameof?
For some reason my designer isn't working well with G.Sharada's solution, though it works great in runtime.
I went a slightly different route:
public class NameOfExtension : MarkupExtension
{
private readonly PropertyPath _propertyPath;
public NameOfExtension(Binding binding)
{
_propertyPath = binding.Path;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
var indexOfLastVariableName = _propertyPath.Path.LastIndexOf('.');
return _propertyPath.Path.Substring(indexOfLastVariableName + 1);
}
}
This way I can do:
<TextBlock Text="{local:NameOf {Binding Property1.Property2}}" />
This is not a replacement obviously since we may not have an instantiated object to bind to. I suppose I could have 2 constructors, one which takes a binding, and the other a Member string.
You can create a custom markup extension.
For example:
[ContentProperty(nameof(Member))]
public class NameOfExtension : MarkupExtension
{
public Type Type { get; set; }
public string Member { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (serviceProvider == null)
throw new ArgumentNullException(nameof(serviceProvider));
if (Type == null || string.IsNullOrEmpty(Member) || Member.Contains("."))
throw new ArgumentException("Syntax for x:NameOf is Type={x:Type [className]} Member=[propertyName]");
var pinfo = Type.GetRuntimeProperties().FirstOrDefault(pi => pi.Name == Member);
var finfo = Type.GetRuntimeFields().FirstOrDefault(fi => fi.Name == Member);
if (pinfo == null && finfo == null)
throw new ArgumentException($"No property or field found for {Member} in {Type}");
return Member;
}
}
Sample usage: