Вот небольшой пример. Я сделал это в Silverlight, поэтому я думаю, вам придется изменить его для работы в WPF. Это не полный, но это отправная точка. Возможно, вы захотите использовать свойство Tag в своих элементах управления, чтобы определить, какие из них нуждаются в исправлении индекса вкладки.
XAML:
<UserControl x:Class="SilverlightApplication6.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignWidth="640"
d:DesignHeight="480">
<Grid x:Name="LayoutRoot">
<StackPanel>
<ItemsControl ItemsSource="{Binding}"
Name="myItemsControl">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ComboBox Grid.Column="0"
ItemsSource="{Binding Source={StaticResource SomeItems}}"
IsSynchronizedWithCurrentItem="False"
SelectedItem="{Binding Path=SomeValue, Mode=TwoWay}"
DisplayMemberPath="Name"
TabIndex="20" />
<ComboBox Grid.Column="1"
ItemsSource="{Binding Source={StaticResource SomeOtherItems}}"
IsSynchronizedWithCurrentItem="False"
SelectedItem="{Binding Path=SomeOtherValue, Mode=TwoWay}"
DisplayMemberPath="Value"
TabIndex="21" />
<TextBox HorizontalContentAlignment="Stretch"
Grid.Column="2"
TabIndex="22">
<TextBox.Text>
<Binding Path="Wert"
Mode="TwoWay" />
</TextBox.Text>
</TextBox>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button Content="Fix Tab indexes" Click="Button_Click"
TabIndex="999"
></Button>
</StackPanel>
</Grid>
</UserControl>
И С #:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;
namespace SilverlightApplication6
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
this.DataContext = new List<int>() { 1, 2, 3, 4, 5 };
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var controls = new List<Control>();
GetChildrenOfSpecificType<Control>(this, ref controls, false);
var index = 1;
controls.ForEach(control =>
{
if (control is ComboBox || control is TextBox)
{
control.TabIndex = index;
index++;
}
});
}
private static void GetChildrenOfSpecificType<T>(DependencyObject parent, ref List<T> resultList, bool getSingle) where T : class
{
if (parent == null)
return;
else
{
int cnt = VisualTreeHelper.GetChildrenCount(parent);
if (cnt > 0)
{
for (int i = 0; i < cnt; i++)
{
var d = VisualTreeHelper.GetChild(parent, i);
if (d is T)
{
resultList.Add(d as T);
if (getSingle)
return;
}
GetChildrenOfSpecificType<T>(d, ref resultList, getSingle);
}
}
}
}
}
}