How to get the name of Xamarin.Forms element from object?

10,946

I'm 100% sure there's a way to refactor your code to avoid the need you have, but for the sake of answering, here's how you could get the name of any objects:

We know for sure that any object tagged with x:Name will create a field of the same name.

So, using reflection, you should be able to get all the fields defined in your page, compare them against your object, and return the field name if it matches.

I haven't tested this, but that should work, or at least put you on the right track

string GetNameOf(object topLevelXaml, object reference)
{
    var fields = topLevelXaml.GetType().GetFields();
    foreach (var fi in fields) {
        var value = fi.GetValue(topLevelXaml);
        if (value != reference)
            continue;
        return fi.Name;
    }
    return null;
}

But again, you shouldn't probably need this at all.

Share:
10,946
testing
Author by

testing

Updated on June 05, 2022

Comments

  • testing
    testing almost 2 years

    Views like Button, Entry, Label, Picker and so on can have a x:Name attribute.

    <Label x:Name="myLabelName" Text="Some text" />
    

    x is defined as xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml".

    Now I want to work with unclassified items and therefore I use object as type.

    How do I get the x:Name attribute as string in code from a object? I don't know the type at this stage.

    Edit:

    To make things more clear I want to post some code. I have a normal XAML page like this:

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="XamlSamples.HelloXamlPage">
        <Label x:Name="myLabelName" Text="Some text" />
    </ContentPage>
    

    In the code-behind file I can get the x:Name attribute if I do nameof(this.myLabelName). But how is this done if you have object only?

    public partial class HelloXamlPage
    {
        public HelloXamlPage()
        {
            InitializeComponent();
    
            List<string> itemsWhichPassTheCheck = this.Check(new List<object>() { this.myLabelName });
        }
    }
    
    private List<string> Check(List<object> itemList)
    {
        // do some check here ...
        // here I have only object and I want to get the x:Name attribute thereof
    }
    
  • testing
    testing over 7 years
    I get 'ReflectionExtensions.GetFields(Type)' is inaccessible due to its protection level. Now I use GetRuntimeFields() instead and I get the name. For topLevelXaml I use this (the current page). But you are right, I'll rethink my approach.