I came across an interesting problem recently: How do you assign AutomationIds automatically for Items in an ItemsControl?
<UserControl
x:Class="ThinkFarAhead.AutoAutomationId.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ThinkFarAhead.AutoAutomationId"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel>
<ItemsControl x:Name="ItemsControl">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock
local:AutomationHelper.Parent=
"{Binding ElementName=ItemsControl}"
local:AutomationHelper.CurrentItem=
"{Binding Path=DataContext,
RelativeSource={RelativeSource TemplatedParent}}"
local:AutomationHelper.IndexedId="Message{0}"
AutomationProperties.AutomationId=
"{Binding (local:AutomationHelper.IndexedId),
RelativeSource={RelativeSource Self}}"
Text="{Binding (AutomationProperties.AutomationId),
RelativeSource={RelativeSource Self}}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
</UserControl>
namespace ThinkFarAhead.AutoAutomationId
{
using System.Windows;
using System.Windows.Controls;
public static class AutomationHelper
{
#region Constants and Fields
public static DependencyProperty CurrentItemProperty =
DependencyProperty.RegisterAttached(
"CurrentItem",
typeof(object),
typeof(AutomationHelper),
new PropertyMetadata(null)
);
public static DependencyProperty IndexedIdProperty =
DependencyProperty.RegisterAttached(
"IndexedId",
typeof(string),
typeof(AutomationHelper),
new PropertyMetadata(null)
);
public static DependencyProperty ParentProperty =
DependencyProperty.RegisterAttached(
"Parent",
typeof(ItemsControl),
typeof(AutomationHelper),
new PropertyMetadata(null)
);
#endregion
#region Public Methods
public static object GetCurrentItem(DependencyObject element)
{
return element.GetValue(CurrentItemProperty);
}
public static string GetIndexedId(DependencyObject element)
{
return element.GetValue(IndexedIdProperty) as string;
}
public static ItemsControl GetParent(DependencyObject element)
{
return element.GetValue(ParentProperty) as ItemsControl;
}
public static void SetCurrentItem
(
DependencyObject element, object value
)
{
element.SetValue(CurrentItemProperty, value);
}
public static void SetIndexedId
(
DependencyObject element, string value
)
{
value = string.Format(value,
GetParent(element)
.Items
.IndexOf(GetCurrentItem(element)));
element.SetValue(IndexedIdProperty, value);
}
public static void SetParent
(
DependencyObject element, ItemsControl value
)
{
element.SetValue(ParentProperty, value);
}
#endregion
}
}
namespace ThinkFarAhead.AutoAutomationId
{
using System.Collections.Generic;
using System.Windows.Controls;
public partial class MainPage : UserControl
{
#region Constructors and Destructors
public MainPage()
{
this.InitializeComponent();
var list = new List<string>();
list.Add("Zero");
list.Add("One");
list.Add("Two");
list.Add("Three");
list.Add("Four");
list.Add("Five");
list.Add("Six");
list.Add("Seven");
list.Add("Eight");
list.Add("Nine");
list.Add("Ten");
this.ItemsControl.ItemsSource = list;
}
#endregion
}
}
Hope it helps somebody!