Bug 41081 - Make AutomationId a bindable property
Summary: Make AutomationId a bindable property
Status: RESOLVED FEATURE
Alias: None
Product: Forms
Classification: Xamarin
Component: Forms ()
Version: 2.3.0
Hardware: Macintosh Mac OS
: Normal enhancement
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2016-05-13 18:35 UTC by Jon Goldberger [MSFT]
Modified: 2016-10-11 19:58 UTC (History)
5 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Sample with Label subclass, MyLabel, with added bound property. (420.08 KB, application/zip)
2016-05-16 23:06 UTC, Jon Goldberger [MSFT]
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FEATURE

Description Jon Goldberger [MSFT] 2016-05-13 18:35:38 UTC
## Description

A customer has requested that AutomationId be a bindable property so they can bind the value they want to use in testing to their view.
Comment 1 Jon Goldberger [MSFT] 2016-05-13 18:44:47 UTC
Note I did suggest workaround of creating their own subclass for the view and adding their own bindable property, which can then be assigned to the AccessibilityIdentifier in the `Xamarin.Forms.Forms.ViewInitialized` event handler.
Comment 2 John Hardman 2016-05-16 13:17:39 UTC
I have also just hit the issue of AutomationId not being bindable in XF 2.2.0.31

Will go with the subclass workaround for the time being, but this does need fixing. That ClassId is bindable but AutomationId is not shows it is inconsistent.
Comment 3 Peter Murphy 2016-05-16 15:38:39 UTC
Hi John and others,

It might help if you upvote my suggestion here:

https://xamarin.uservoice.com/forums/144858-xamarin-platform-suggestions/suggestions/13865469-make-automationid-a-bindableproperty-in-xamarin-fo

Thanks,

Peter.
Comment 7 Jon Goldberger [MSFT] 2016-05-16 23:06:50 UTC
Created attachment 16016 [details]
Sample with Label subclass, MyLabel, with added bound property.

As I was pressed to clarify the suggested workaround, I discovered something. I was able to make a subclass of a Label with an additional bound property, MyAutomationId. And while this worked on Android, it did not on iOS. On Android when the Forms.ViewInitialized event runs, the bound properties are set, IOW what I set for MyAutomationId was available to be assigned to the e.NativeView.ContentDescription property. But on iOS when the Forms.ViewInitialized event, all of the Label subclasses bound properties are null, IOW they appear to not be set yet. 

I am attaching a modified version of TipCalc to demonstrate this. Please let me know if there is some mistake I made as I am a noob when it comes to creating bindable properties. 

Run the project on Android and you will see the following output in the console:
Test MyAutomationId: BoundAutomationId

on iOS you just get:
Test MyAutomationId:

And if I look over the properties for the MyLabel instance during the ViewInitialized event handler, I see that Text,  MyAutomationId , and other bound fields are null.
Comment 8 Peter Murphy 2016-05-17 10:21:11 UTC
For those interested, the code in Jon's sample above has done the trick for us.  Here's our final implementation:

public class BindableStack : StackLayout
{
	public static readonly BindableProperty StyleIdProperty = BindableProperty.Create(
		"StyleIdBindableProperty",
		typeof(string), 
		typeof(View), 
		null, 
		BindingMode.OneWay, 
		null, (bindable, oldValue, newValue) => {
			var thisView = bindable as BindableStack;

			if (thisView != null)
				thisView.StyleId = newValue as string;
		}
	);
}

Then we can use it like this:

var wrapperLayout = new BindableStack();
wrapperLayout.SetBinding (BindableStack.StyleIdProperty, "ElementId");

Thank you!