在Expander中与Embedded ToggleButton的ControlTemplate交互

时间:2014-05-30 20:39:52

标签: silverlight xaml templates controltemplate

我真的希望有人可以在这里教我一些新东西,因为必须有一条更清洁的路线。

在工具包的Style控件的Expander模板中,有一个嵌入式ToggleButton处理扩展器区域的切换。我想找到一种更好的方法来触摸特定的UIElement,而不必重申Expander的整个风格。例如,如果它位于Style;

Expander模板中
<ToggleButton x:Name="ExpanderButton"
              Grid.Row="0" Grid.Column="0"
              MinWidth="0" MinHeight="0"
              Margin="1"
              HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
              VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
              Content="{TemplateBinding Header}"
              ContentTemplate="{TemplateBinding HeaderTemplate}"
              FontFamily="{TemplateBinding FontFamily}"
              FontSize="{TemplateBinding FontSize}"
              FontStretch="{TemplateBinding FontStretch}"
              FontStyle="{TemplateBinding FontStyle}"
              FontWeight="{TemplateBinding FontWeight}"
              Foreground="{TemplateBinding Foreground}"
              IsChecked="{TemplateBinding IsExpanded}"
              Padding="{TemplateBinding Padding}"
              Template="{StaticResource TheExpanderToggleButtonStyle}" />

我们看到Template="{StaticResource TheExpanderToggleButtonStyle}"只指向ControlTemplate的另一个ToggleButton权利?所以我希望我可以在实例级别做一些事情,只为ToggleButton设置一个不同的模板,可能就像它一样;

<toolkit:Expander>
   <toolkit:Expander.Resources>
      <Style TargetType="ToggleButton">
          <Setter Property="Template" Value="{StaticResource ADifferentToggleButtonStyle}"/>           
      </Style>
   </toolkit:Expander.Resources>

   <TextBlock Text="Blah"/>

</toolkit:Expander>

......或者是同一类型的概念,我可以通过多种不同的方式来思考这个例子,我真的没想到它会起作用,它恰好是我在发布之前尝试过的最后一个,试图把它扔在标题上,我甚至不知道有多少不同的尝试,但无济于事。所以,我只是复制这两个模板只是为了制作一个自定义扩展器,但就像我说的,我希望有人可以教我一个更好的方式,这将是非常有用的未来。干杯!

1 个答案:

答案 0 :(得分:0)

<toolkit:Expander
    my:ExpanderExtensions.ToggleButtonStyle="{StaticResource MyToggleBtnStyle}"/>

代码:

public static class ExpanderExtensions
{
    public static Style GetToggleButtonStyle( Expander expander )
    {
        return (Style) expander.GetValue( ToggleButtonStyleProperty );
    }

    public static void SetToggleButtonStyle( Expander expander, Style value )
    {
        expander.SetValue( ToggleButtonStyleProperty, value );
    }

    public static readonly DependencyProperty ToggleButtonStyleProperty =
        DependencyProperty.RegisterAttached( "ToggleButtonStyle",
        typeof( Style ), typeof( ExpanderExtensions ),
                    new PropertyMetadata( OnToggleButtonStyleChanged ) );

    private static void OnToggleButtonStyleChanged(
                DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Expander expander = d as Expander;
        if (expander == null) return;

        if (expander.IsLoaded())
            ApplyToggleButtonStyle(expander, e.NewValue as Style);
        else
            expander.Loaded += OnExpanderLoaded;
    }

    private static void OnExpanderLoaded(object sender, RoutedEventArgs e)
    {
            Expander expander = (Expander) sender;
            expander.Loaded -= OnExpanderLoaded;
            ApplyToggleButtonStyle( expander, GetToggleButtonStyle(expander) );
    }

    private static void ApplyToggleButtonStyle(
                Expander expander, Style toggleButtonStyle)
    {
            //VisualTreeExtensions.GetVisualDescendants
            // is from System.Windows.Controls.Toolkit.dll
        var expanderToggleButton = expander.GetVisualDescendants().
                        OfType<ToggleButton>().First();
        expanderToggleButton.Style = toggleButtonStyle;
    }
}

public static class ControlExtensions
{
    public static bool IsLoaded(this FrameworkElement element)
    {
        return element.GetVisualChildren().Any();

        //I'm not sure if this alternative is better:
        //return control.GetVisualParent() != null;
    }
}

[修改]您可以通过Template设置Style,但如果您不想设置样式,只需将附加属性的类型更改为ControlTemplate并调整ApplyToggleButtonStyle方法。