问题
I'm dynamically adding WPF ComboBox-es and I want to be able to select the added ComboBoxes with the 'TAB' key. (Dynamically generate TabIndex or something)
As it actually is:
What I want:
How would you do that?
This is the code:
<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" LostKeyboardFocus="TextBox_FormatAfterLostFocus">
<TextBox.Text>
<Binding Path="Wert" Mode="TwoWay" />
</TextBox.Text>
</TextBox>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Thanks in advance !
回答1:
Here is a small example. I did this in Silverlight, so I guess you will have to modify it to work in WPF. It is not complete, but it is a starting point. You might want to use the Tag property on your controls to identify which of them need tab index fixing.
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>
And C#:
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);
}
}
}
}
}
}
来源:https://stackoverflow.com/questions/2116802/wpf-tabstop-tabindex-in-itemscontrol