2009-07-01 7 views
20

Lorsque vous utilisez la commande WPF Expander, elle est affichée avec les touches fléchées "Up" et "Down" par défaut. Y a-t-il un moyen de cacher ces flèches haut et bas?Masquage des flèches pour la commande d'extension WPF

MISE À JOUR:

j'ai réussi à enlever les flèches en créant un ControlTemplate mais maintenant la capacité d'expansion est allé aussi:

<ContentPresenter Content="{TemplateBinding Expander.Header}"></ContentPresenter> 
      <ContentPresenter Content="{TemplateBinding Expander.Content}"></ContentPresenter> 



<Expander Template="{StaticResource ExpanderControlTemplate}" IsExpanded="False" Cursor="Hand">    

       <Expander.Header> 
       <Border Style="{StaticResource FeedTitleStyle}"> 
       <DockPanel Width="Auto"> 
        <TextBlock DockPanel.Dock="Left" FontSize="16" Text="IronRuby in Action!" />     
       </DockPanel>   

      </Border>     
       </Expander.Header> 
       <Expander.Content>      
        <TextBlock Text="This is the decriprion!" /> 
       </Expander.Content> 

      </Expander> 

Répondre

53

Malheureusement, le ContentPresenter intérieur du ExpanderTemplate pour l'en-tête est dans la même grille comme la flèche, la définition du HeaderTemplate ne nous aidera pas. En utilisant Mole, nous pouvons voir que le ToggleButton a une ellipse - représentant le cercle, un chemin - représentant la flèche, et le ContentPresenter qui affiche ce que vous avez défini pour la propriété Header.

alt text http://i42.tinypic.com/2ihlzzr.jpg

Maintenant que nous savons que la mise en page réelle du Expander, il y a quelques façons dont nous pourrions aller sur la modifier. Créer un tout nouveau ControlTemplate pour l'Expander, ou obtenir les pièces que nous voulons supprimer et les supprimer/masquer.

Mise à jour: Après avoir généré un modèle pour l'expandeur, il suffit de passer et de supprimer l'ellipse et le chemin de chaque style ToggleButton.

<Style x:Key="ExpanderHeaderFocusVisual"> 
    <Setter Property="Control.Template"> 
    <Setter.Value> 
     <ControlTemplate> 
      <Border> 
       <Rectangle SnapsToDevicePixels="true" 
          Margin="0" 
          Stroke="Black" 
          StrokeDashArray="1 2" 
          StrokeThickness="1" /> 
      </Border> 
     </ControlTemplate> 
    </Setter.Value> 
    </Setter> 
</Style> 

<Style x:Key="ExpanderDownHeaderStyle" 
     TargetType="{x:Type ToggleButton}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type ToggleButton}"> 
       <Border Padding="{TemplateBinding Padding}"> 
        <Grid SnapsToDevicePixels="False" 
          Background="Transparent"> 
         <ContentPresenter SnapsToDevicePixels="True" 
              HorizontalAlignment="Left" 
              VerticalAlignment="Center" 
              RecognizesAccessKey="True" /> 
        </Grid> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 
<Style x:Key="ExpanderRightHeaderStyle" 
     TargetType="{x:Type ToggleButton}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type ToggleButton}"> 
       <Border Padding="{TemplateBinding Padding}"> 
        <Grid SnapsToDevicePixels="False" 
          Background="Transparent"> 
         <ContentPresenter SnapsToDevicePixels="True" 
              HorizontalAlignment="Center" 
              VerticalAlignment="Top" 
              RecognizesAccessKey="True" /> 
        </Grid> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 
<Style x:Key="ExpanderUpHeaderStyle" 
     TargetType="{x:Type ToggleButton}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type ToggleButton}"> 
       <Border Padding="{TemplateBinding Padding}"> 
        <Grid SnapsToDevicePixels="False" 
          Background="Transparent"> 
         <ContentPresenter SnapsToDevicePixels="True" 
              HorizontalAlignment="Left" 
              VerticalAlignment="Center" 
              RecognizesAccessKey="True" /> 
        </Grid> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 
<Style x:Key="ExpanderLeftHeaderStyle" 
     TargetType="{x:Type ToggleButton}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type ToggleButton}"> 
       <Border Padding="{TemplateBinding Padding}"> 
        <Grid SnapsToDevicePixels="False" 
          Background="Transparent"> 
         <ContentPresenter SnapsToDevicePixels="True" 
              HorizontalAlignment="Center" 
              VerticalAlignment="Top" 
              RecognizesAccessKey="True" /> 
        </Grid> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 
<Style x:Key="ArrowlessExpanderTemplate" 
     TargetType="{x:Type Expander}"> 
    <Setter Property="Foreground" 
      Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" /> 
    <Setter Property="Background" 
      Value="Transparent" /> 
    <Setter Property="HorizontalContentAlignment" 
      Value="Stretch" /> 
    <Setter Property="VerticalContentAlignment" 
      Value="Stretch" /> 
    <Setter Property="BorderBrush" 
      Value="Transparent" /> 
    <Setter Property="BorderThickness" 
      Value="1" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type Expander}"> 
       <Border SnapsToDevicePixels="true" 
         Background="{TemplateBinding Background}" 
         BorderBrush="{TemplateBinding BorderBrush}" 
         BorderThickness="{TemplateBinding BorderThickness}" 
         CornerRadius="3"> 
        <DockPanel> 
         <ToggleButton FontFamily="{TemplateBinding FontFamily}" 
             FontSize="{TemplateBinding FontSize}" 
             FontStretch="{TemplateBinding FontStretch}" 
             FontStyle="{TemplateBinding FontStyle}" 
             FontWeight="{TemplateBinding FontWeight}" 
             Foreground="{TemplateBinding Foreground}" 
             HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" 
             Padding="{TemplateBinding Padding}" 
             VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" 
             FocusVisualStyle="{StaticResource ExpanderHeaderFocusVisual}" 
             Margin="1" 
             MinHeight="0" 
             MinWidth="0" 
             x:Name="HeaderSite" 
             Style="{StaticResource ExpanderDownHeaderStyle}" 
             Content="{TemplateBinding Header}" 
             ContentTemplate="{TemplateBinding HeaderTemplate}" 
             ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}" 
             DockPanel.Dock="Top" 
             IsChecked="{Binding Path=IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" /> 
         <ContentPresenter Focusable="false" 
              Visibility="Collapsed" 
              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
              Margin="{TemplateBinding Padding}" 
              x:Name="ExpandSite" 
              VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
              DockPanel.Dock="Bottom" /> 
        </DockPanel> 
       </Border> 
       <ControlTemplate.Triggers> 
        <Trigger Property="IsExpanded" 
          Value="true"> 
         <Setter Property="Visibility" 
           TargetName="ExpandSite" 
           Value="Visible" /> 
        </Trigger> 
        <Trigger Property="ExpandDirection" 
          Value="Right"> 
         <Setter Property="DockPanel.Dock" 
           TargetName="ExpandSite" 
           Value="Right" /> 
         <Setter Property="DockPanel.Dock" 
           TargetName="HeaderSite" 
           Value="Left" /> 
         <Setter Property="Style" 
           TargetName="HeaderSite" 
           Value="{StaticResource ExpanderRightHeaderStyle}" /> 
        </Trigger> 
        <Trigger Property="ExpandDirection" 
          Value="Up"> 
         <Setter Property="DockPanel.Dock" 
           TargetName="ExpandSite" 
           Value="Top" /> 
         <Setter Property="DockPanel.Dock" 
           TargetName="HeaderSite" 
           Value="Bottom" /> 
         <Setter Property="Style" 
           TargetName="HeaderSite" 
           Value="{StaticResource ExpanderUpHeaderStyle}" /> 
        </Trigger> 
        <Trigger Property="ExpandDirection" 
          Value="Left"> 
         <Setter Property="DockPanel.Dock" 
           TargetName="ExpandSite" 
           Value="Left" /> 
         <Setter Property="DockPanel.Dock" 
           TargetName="HeaderSite" 
           Value="Right" /> 
         <Setter Property="Style" 
           TargetName="HeaderSite" 
           Value="{StaticResource ExpanderLeftHeaderStyle}" /> 
        </Trigger> 
        <Trigger Property="IsEnabled" 
          Value="false"> 
         <Setter Property="Foreground" 
           Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" /> 
        </Trigger> 
       </ControlTemplate.Triggers> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

De plus, nous pourrions créer un AttachedProperty et définir les parties de flèche et cercle à la place se sont effondrés.

Voici notre AttachedProperty:

public class AttachedProperties 
{ 
    #region HideExpanderArrow AttachedProperty 

    [AttachedPropertyBrowsableForType(typeof(Expander))] 
    public static bool GetHideExpanderArrow(DependencyObject obj) 
    { 
     return (bool)obj.GetValue(HideExpanderArrowProperty); 
    } 

    [AttachedPropertyBrowsableForType(typeof(Expander))] 
    public static void SetHideExpanderArrow(DependencyObject obj, bool value) 
    { 
     obj.SetValue(HideExpanderArrowProperty, value); 
    } 

    // Using a DependencyProperty as the backing store for HideExpanderArrow. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty HideExpanderArrowProperty = 
     DependencyProperty.RegisterAttached("HideExpanderArrow", typeof(bool), typeof(AttachedProperties), new UIPropertyMetadata(false, OnHideExpanderArrowChanged)); 

    private static void OnHideExpanderArrowChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) 
    { 
     Expander expander = (Expander)o; 

     if (expander.IsLoaded) 
     { 
      UpdateExpanderArrow(expander, (bool)e.NewValue); 
     } 
     else 
     { 
      expander.Loaded += new RoutedEventHandler((x, y) => UpdateExpanderArrow(expander, (bool)e.NewValue)); 
     } 
    } 

    private static void UpdateExpanderArrow(Expander expander, bool visible) 
    { 
     Grid headerGrid = 
      VisualTreeHelper.GetChild(
       VisualTreeHelper.GetChild(
         VisualTreeHelper.GetChild(
          VisualTreeHelper.GetChild(
           VisualTreeHelper.GetChild(
            expander, 
            0), 
           0), 
          0), 
         0), 
        0) as Grid; 

     headerGrid.Children[0].Visibility = visible ? Visibility.Collapsed : Visibility.Visible; // Hide or show the Ellipse 
     headerGrid.Children[1].Visibility = visible ? Visibility.Collapsed : Visibility.Visible; // Hide or show the Arrow 
     headerGrid.Children[2].SetValue(Grid.ColumnProperty, visible ? 0 : 1); // If the Arrow is not visible, then shift the Header Content to the first column. 
     headerGrid.Children[2].SetValue(Grid.ColumnSpanProperty, visible ? 2 : 1); // If the Arrow is not visible, then set the Header Content to span both rows. 
     headerGrid.Children[2].SetValue(ContentPresenter.MarginProperty, visible ? new Thickness(0) : new Thickness(4,0,0,0)); // If the Arrow is not visible, then remove the margin from the Content. 
    } 

    #endregion 
} 

Je suis juste voyager directement à la grille qui contient la « flèche » et le contenu d'en-tête, au lieu d'essayer de trouver les contrôles par nom, donc cela ne fonctionnera pas exactement comme si vous reformulez également l'expandeur dans une structure différente. Une fois que nous avons localisé la grille contenant, nous pouvons définir la flèche et le cercle à réduire, et nous assurer que le contenu de l'en-tête est complètement déplacé vers la gauche.

Pour utiliser la propriété ci-joint, nous pouvons simplement mettre sur l'élément en XAML:

<StackPanel> 
    <Expander x:Name="uiExpander" 
       local:AttachedProperties.HideExpanderArrow="True"> 
     <Expander.Header> 
      <Border> 
       <DockPanel Width="Auto"> 
        <TextBlock DockPanel.Dock="Left" 
           FontSize="16" 
           Text="IronRuby in Action!" /> 
       </DockPanel> 
      </Border> 
     </Expander.Header> 
     <Expander.Content> 
      <TextBlock Text="This is the decriprion!" /> 
     </Expander.Content> 
    </Expander> 

    <Button Content="Click to Show/Hide Expander Arrow" 
      Click="Button_Click" /> 

</StackPanel> 

Et dans le code:

void Button_Click(object sender, RoutedEventArgs e) 
{ 
    uiExpander.SetValue(
     AttachedProperties.HideExpanderArrowProperty, 
     !(bool)uiExpander.GetValue(AttachedProperties.HideExpanderArrowProperty)); 
} 
+0

homme réponse Impressionnant! Et merci aussi pour l'outil Mole que je ne connaissais pas sur Mole! – azamsharp

+1

+1 pour une réponse solide qui n'a pas retenu l'attention ou le mérite qu'elle mérite. :) –

+0

Y at-il un moyen de lier le IsEnabled de la flèche à une valeur booléenne, je suis à la recherche d'une solution soignée, s'il n'y en a pas, je vais juste y renoncer. – Shimmy