Reputation: 13
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
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
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.
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