我找到了一個方法,但有一些更好的東西。
通過Mole查看Expander,或者查看它由Blend生成的ControlTemplate,我們可以看到響應Space/Enter/Click/etc的標頭部分實際上是一個ToggleButton。現在壞消息了,因爲Header的ToggleButton對Expander的擴展屬性Up/Down/Left/Right有不同的佈局,所以它已經通過擴展器的ControlTemplate爲其指定了樣式。這阻礙了我們在Expander的資源中創建一個默認的ToggleButton樣式。
alt text http://i44.tinypic.com/2dlq1pl.png
如果你有機會獲得後面的代碼,或不介意添加代碼隱藏的資源字典的膨脹機,那麼你就可以訪問切換按鈕,並在擴展設置tabIndex。 Loaded事件,像這樣:
<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;
}
}
您也可以只投sender對象到精通如果你需要它與多個擴展器一起工作,也是如此。 另一種選擇是爲擴展器創建自己的ControlTemplate並在其中進行設置。
編輯 我們也可以將代碼部分移動到AttachedProperty,使它更清潔和更容易使用:
<Expander local:ExpanderHelper.HeaderTabIndex="20">
...
</Expander>
而且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;
}
}
}
我更新了我的答案,你想 – jjxtra 2009-06-16 02:47:19