2008-12-17 6 views
5

J'utilise un ScrollViewer dans le cadre de mon application Silverlight. Il a une orientation horizontale, et je voudrais qu'il apparaisse de telle sorte que seuls les boutons de défilement apparaissent, mais pas la barre de défilement elle-même. Quelque chose comme ce rendu ASCII brut:Silverlight Scrollviewer avec seulement des boutons

------------------------------------------------------ 
| |           | | 
| < |    Content Here    | > | 
| |           | | 
------------------------------------------------------ 

Je sais que je pourrais utiliser la fonctionnalité de texturation, mais tous les échantillons que j'ai vu que changer l'apparence de tous les éléments, et non leur positionnement brut, ou si elles même apparaître. Est-il possible de faire cela, et quelqu'un pourrait-il donner un aperçu de ce à quoi pourrait ressembler le modèle?

Répondre

1

J'ai fait quelque chose de similaire et la meilleure façon de le faire était de mettre votre contenu dans une visionneuse de défilement et d'éteindre les barres de défilement. Ensuite, codez vos boutons pour faire défiler le scrollviewer.

Editer: Répondre au commentaire sur aucune façon de gérer le dimensionnement.

Tout d'abord, vous devez générer ce contrôle en tant que ContentControl. Il devrait avoir un modèle défini dans generic.xaml qui a vos contrôles de bouton plus la visionneuse de défilement. Quelque chose comme:

<Canvas x:Name="root"> 
    <Button x:Name="left" Content="<"/> 
    <Button x:Name="right" Content=">"/> 
    <ScrollViewer x:Name="viewer" BorderThickness="0" VerticalScrollBarVisibility="Hidden"> 
    <ContentPresenter /> 
    </ScrollViewer> 
</Canvas> 

Ensuite, dans votre contrôle, vous devrez passer outre OnApplyTemplate:

public override void OnApplyTemplate() 
{ 
    base.OnApplyTemplate(); 

    left = GetTemplateChild("left") as Button; 
    left.Click += new RoutedEvent(YourHandler); 
    right = GetTemplateChild("right") as Button; 
    right.Click += new RoutedEvent(YourHandler); 
    // position your scroll buttons here, not writing that code 
    scroll = GetTemplateChild("viewer") as ScrollViewer; 
    root = GetTemplateChild("root") as Canvas; 

    var fe = this.Content as FrameworkElement; 
    if (fe != null) 
    { 
    fe.SizeChanged += new SizeChangedEventHandler(fe_SizeChanged); 
    } 
} 

void fe_SizeChanged(object sender, SizeChangedEventArgs e) 
{ 
    this.InvalidateMeasure(); 
} 

protected override Size ArrangeOverride(Size finalSize) 
{ 
    if (!double.IsInfinity(scroll.ViewportHeight)) 
    { 
    left.Visibility = (scroll.HorizontalOffset > 0); 
    right.Visibility = (scroll.HorizontalOffset < ScrollableHeight); 
    } 
    return base.ArrangeOverride(finalSize); 
} 

protected override Size MeasureOverride(Size availableSize) 
{ 
    scroll.Measure(availableSize); 
    return scroll.DesiredSize; 
} 

Dans votre bouton gestionnaires de clic vous devez (1), faites défiler le spectateur et (2) vérifier la nouvelle valeur de l'objet HorizontalOffset pour voir si vous devez masquer ou afficher l'un des boutons.

Avertissement: Ce code ne fonctionne probablement pas tel quel puisqu'il a été écrit à la main et basé sur un exemple différent.

+0

Le problème avec cette méthode est que je ne vois pas un événement que je puisse joindre à, qui me notifierait lorsque la fenêtre a été modifiée de telle sorte que les boutons doivent être rendus visibles. Donc en effet, je devrais rendre les boutons toujours visibles, ce que je n'aime pas. – Nick

1

Voici une autre option. Remplacer le modèle par défaut pour SCrollviewer et gérer les boutons comme PageUp/PageDown. Mon exemple ci-dessous est un scrollviewer qui défile verticalement. Vous pouvez facilement passer au défilement horizontal et changer les gestionnaires de PageUp/PageDown aux gestionnaires Left et Right.

<ControlTemplate TargetType="{x:Type ScrollViewer}" x:Key="ButtonOnlyScrollViewer"> 
     <ControlTemplate.Resources> 
      <!-- Add style here for repeat button seen below --> 
     </ControlTemplate.Resources> 
     <Grid> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="Auto"/> 
       <RowDefinition Height="*"/> 
       <RowDefinition Height="Auto"/> 
      </Grid.RowDefinitions> 

      <RepeatButton Grid.Row="0" 
          Foreground="White" 
          Background="Yellow" 
          HorizontalAlignment="Stretch" 
          Command="ScrollBar.PageUpCommand" 
          Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"> 
      </RepeatButton> 

      <ScrollContentPresenter 
       CanContentScroll="{TemplateBinding CanContentScroll}" 
       Grid.Row="1" 
       Content="{TemplateBinding Content}" 
       Width="{TemplateBinding Width}" 
       Height="{TemplateBinding Height}" 
       Margin="{TemplateBinding Margin}"/> 

      <RepeatButton Grid.Row="2" Background="Black" Foreground="White" Command="ScrollBar.PageDownCommand"> 
      </RepeatButton> 
     </Grid> 
    </ControlTemplate> 
+0

StackOverflow est boiteux. Mes modifications ne s'affichent pas. Évidemment, l'exemple ci-dessus manque certaines informations en haut du modèle de contrôle, mais dans la vue d'édition, tout est là. Il est possible de simplement remplacer le modèle ScrollViewer pour obtenir l'effet du bouton uniquement. – Louis

+0

L'envoyer à pastebin? –

+0

Cela semble être une solution WPF. Comment faire dans Silverlight? La commande = "ScrollBar.PageUpCommand" ne fonctionne pas dans Silverlight. –

0

J'ai cherché une solution de travail pour beaucoup de temps maintenant. Et sur la base de la solution de Louis, j'ai réussi à le faire fonctionner. (en WPF)

Cette solution est pour horizontal défilement.

Tout d'abord, ajouter ListView:

<ListView ItemsSource="{Binding Items}"> 
     <ListView.ItemsPanel> 
      <ItemsPanelTemplate> 
       <StackPanel Orientation="Horizontal"/> 
      </ItemsPanelTemplate> 
     </ListView.ItemsPanel> 
     <ListView.Template> 
      <ControlTemplate> 
       <ScrollViewer Template="{StaticResource ButtonOnlyScrollViewer}"> 
        <ItemsPresenter /> 
       </ScrollViewer> 
      </ControlTemplate> 
     </ListView.Template> 
    </ListView> 

Et un modèle de réponse de Louis pour le défilement horizontal modifié:

<ControlTemplate TargetType="{x:Type ScrollViewer}" x:Key="ButtonOnlyScrollViewer"> 
     <Grid> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="Auto"/> 
       <ColumnDefinition Width="*"/> 
       <ColumnDefinition Width="Auto"/> 
      </Grid.ColumnDefinitions> 

      <RepeatButton Content="&lt;" 
          Grid.Column="0" 
          Command="ScrollBar.LineLeftCommand" 
          Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/> 

      <ScrollContentPresenter 
       CanContentScroll="{TemplateBinding CanContentScroll}" 
       Grid.Column="1" 
       Content="{TemplateBinding Content}" 
       Width="{TemplateBinding Width}" 
       Height="{TemplateBinding Height}" 
       Margin="{TemplateBinding Margin}"/> 

      <RepeatButton Content="&gt;" 
          Grid.Column="2" 
          Command="ScrollBar.LineRightCommand" 
          Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/> 
     </Grid> 
    </ControlTemplate>