user3722296
user3722296

Reputation: 13

How to access object name in custom classes using Xamarin.forms?

Recently I have started development using Xamarin.Forms. I am creating an application in which I have to customize the button, so I created customButton class. Now, I want to access the button in custom class using object.name property but I am not able to do that. Can anyone suggest how I can do that.

Code

<local:CustomButton x:Name="signInButton"  Text="Sign In" Clicked="OnLoginButtonClicked"  TextColor ="White" FontSize="15" FontAttributes="Bold"/>

CustomButton class inside Android project

namespace Sample.Droid
{
    class CustomButtonRenderer : ButtonRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
        {
            base.OnElementChanged(e);

            if (Control != null)
            {

                //Want to access button name in if condition, instead of Control.
                //Hope this will help you all in understanding my problem.
            }
        }
    }
}

Thanks

Upvotes: 0

Views: 2314

Answers (2)

Grace Feng
Grace Feng

Reputation: 16652

I can't use the Element.Text property as I will remove the text and set image to my button. I need to use either Tag or Name property

The Name is assigned at the Render processing stage, for android platform, as I said, usually we use id to identify the control. It seems the name property cannot be exposed here, a workaround is that we can expose a property by registering a BindableProperty. For example:

public class MyButton : Button
{
    public string ButtonName
    {
        get { return (string)GetValue(ButtonNameProperty); }
        set { SetValue(ButtonNameProperty, value); }
    }

    public static readonly BindableProperty ButtonNameProperty =
        BindableProperty.Create(
            propertyName: "ButtonName",
            returnType: typeof(string),
            declaringType: typeof(MyButton),
            defaultValue: null,
            propertyChanged: OnButtonNameChanged);

    private static void OnButtonNameChanged(BindableObject bindable, object oldValue, object newValue)
    {
    }
}

Code behind:

public class MyButtonRenderer : ButtonRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
    {
        base.OnElementChanged(e);
        //Element.Id

        if (Element != null)
        {
            var element = Element as MyButton;
            var name = element.ButtonName;
        }
    }
}

A little problem in your code is that the Control in the custom renderer indicates the native control of each platform, the Element is your custom control, so I used Element property here.

And to use this control:

<local:MyButton x:Name="signInButton" Text="custom button" ButtonName="signInButton" />

I know it is annoying to set the name property twice when you use this custom Button, but it's the only method I found for now to get a tag for each custom button from renderer. If you don't need to access this Button in code behind in PCL, then maybe you don't need to set the x:Name property.

Upvotes: 1

Paul Karam
Paul Karam

Reputation: 4210

First of all, and I am not sure if you have it or not, you need to add this line of code at the top of your namespace:

[assembly: ExportRenderer(typeof(CustomButton), typeof(CustomButtonRenderer))]

Second, inside your code you have access to the Element itself, example:

if (control != null)
{
    string buttonText = Element.Text; //In your posted case it will be equal to "Sign In"
}

I am not sure if you can actually access the x:Name attribute from inside the CustomRenderer since it's the class variable name.. But depending on what you're trying to do you have all the Element object that you can work with.

Edit

I couldn't find a way to directly access the name property, but there's a work around that you can make.
In your PCL project, and your CustomButton class you can add a property that you want:

public class CustomButton : Button
{
    public string Name { get; set; }
    //rest of your code
}

In your xaml page, you can add it as a property now like:

<local:CustomButton x:Name="signInButton" Name="signInButton" Text="Sign In" Clicked="OnLoginButtonClicked"  TextColor ="White" FontSize="15" FontAttributes="Bold"/>

And after that in your renderer, where I showed you before, you can now do that:

if (Control != null)
{
    string buttonName = ((CustomButton)Element).Name; //it will have the "signInButton" now.
}

Upvotes: 0

Related Questions