Tôi đã tìm được cách, nhưng phải có điều gì đó tốt hơn.
Nhìn vào Expander qua Mole, hoặc nhìn vào ControlTemplate được tạo bởi Blend, chúng ta có thể thấy phần tiêu đề phản hồi Space/Enter/Click/etc thực sự là một ToggleButton. Bây giờ tin xấu, Bởi vì ToggleButton của Header có một bố cục khác nhau cho các thuộc tính mở rộng của Expander Up/Down/Left/Right, nó đã có kiểu được gán cho nó thông qua ControlTemplate của Expander. Điều đó ngăn cản chúng ta làm một cái gì đó đơn giản như tạo một kiểu ToggleButton mặc định trong Tài nguyên của Expander.
alt text http://i44.tinypic.com/2dlq1pl.png
Nếu bạn có quyền truy cập vào mã phía sau, hoặc không nhớ thêm một CodeBehind vào từ điển Resource rằng nở là vào, sau đó bạn có thể truy cập vào ToggleButton và thiết lập tabIndex trong Expander. sự kiện Loaded, như thế này:
<Expander x:Name="uiExpander"
Header="_abc"
Loaded="uiExpander_Loaded"
TabIndex="20"
IsTabStop="False">
<TextBox TabIndex="30">
</TextBox>
</Expander>
private void uiExpander_Loaded(object sender, RoutedEventArgs e)
{
//Gets the HeaderSite part of the default ControlTemplate for an Expander.
var header = uiExpander.Template.FindName("HeaderSite", uiExpander) as Control;
if (header != null)
{
header.TabIndex = uiExpander.TabIndex;
}
}
Bạn cũng có thể chỉ cast object sender một Exp và cũng vậy, nếu bạn cần nó để làm việc với nhiều bộ mở rộng. Tùy chọn khác, là tạo ControlTemplate của riêng bạn cho Expander (s) và thiết lập nó trong đó.
EDIT Chúng tôi cũng có thể di chuyển phần mã để một AttachedProperty, làm cho nó sạch hơn và dễ dàng hơn để sử dụng:
<Expander local:ExpanderHelper.HeaderTabIndex="20">
...
</Expander>
Và AttachedProperty:
public class ExpanderHelper
{
public static int GetHeaderTabIndex(DependencyObject obj)
{
return (int)obj.GetValue(HeaderTabIndexProperty);
}
public static void SetHeaderTabIndex(DependencyObject obj, int value)
{
obj.SetValue(HeaderTabIndexProperty, value);
}
// Using a DependencyProperty as the backing store for HeaderTabIndex. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HeaderTabIndexProperty =
DependencyProperty.RegisterAttached(
"HeaderTabIndex",
typeof(int),
typeof(ExpanderHelper),
new FrameworkPropertyMetadata(
int.MaxValue,
FrameworkPropertyMetadataOptions.None,
new PropertyChangedCallback(OnHeaderTabIndexChanged)));
private static void OnHeaderTabIndexChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
var expander = o as Expander;
int index;
if (expander != null && int.TryParse(e.NewValue.ToString(), out index))
{
if (expander.IsLoaded)
{
SetTabIndex(expander, (int)e.NewValue);
}
else
{
// If the Expander is not yet loaded, then the Header will not be costructed
// To avoid getting a null refrence to the HeaderSite control part we
// can delay the setting of the HeaderTabIndex untill after the Expander is loaded.
expander.Loaded += new RoutedEventHandler((i, j) => SetTabIndex(expander, (int)e.NewValue));
}
}
else
{
throw new InvalidCastException();
}
}
private static void SetTabIndex(Expander expander, int index)
{
//Gets the HeaderSite part of the default ControlTemplate for an Expander.
var header = expander.Template.FindName("HeaderSite", expander) as Control;
if (header != null)
{
header.TabIndex = index;
}
}
}
Tôi đã cập nhật câu trả lời của mình để làm mọi thứ bạn muốn – jjxtra