2008-12-17 10 views
5

Ich verwende einen ScrollViewer als Teil meiner Silverlight-Anwendung. Es hat eine horizontale Ausrichtung, und ich möchte, dass es so erscheint, dass nur die Bildlaufschaltflächen erscheinen, aber nicht die Bildlaufleiste selbst. So etwas wie dieses rohe ASCII-Rendering:Silverlight Scrollviewer mit nur Schaltflächen

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

Ich weiß, dass ich die Templat-Funktionalität nutzen konnte, aber alle Proben, die ich nur das Aussehen aller Elemente ändern gesehen habe, und nicht ihre rohe Positionierung, oder ob sie sogar erscheinen. Ist es möglich, dies zu tun und könnte jemand einen Überblick darüber geben, wie die Vorlage aussehen könnte?

Antwort

1

Ich habe etwas ähnliches getan, und das Beste, was ich gefunden habe, war, den Inhalt in einen Scroll-Viewer zu bringen und einfach die Bildlaufleisten auszuschalten. Codiere dann deine Knöpfe, um den Scrollviewer zu scrollen.

Bearbeiten: Reagieren auf Kommentar über keine Möglichkeit, mit Sizing umzugehen.

Zunächst einmal würden Sie dieses Steuerelement als ContentControl erstellen. Es sollte eine Vorlage enthalten, die in generic.xaml definiert ist und die Schaltflächensteuerelemente und den Bildlauf-Viewer enthält. Etwas wie:

<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> 

Dann in Ihrer Kontrolle würden Sie OnApplyTemplate außer Kraft setzen müssen:

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; 
} 

In Ihrer Schaltfläche klicken Handler Sie würden müssen (1) bewegen den Betrachter und (2) überprüfen Sie die neuen Wert des HorizontalOffset, um zu sehen, ob Sie eine der Schaltflächen ausblenden oder anzeigen müssen.

Haftungsausschluss: Dieser Code funktioniert wahrscheinlich nicht so, wie es ist, da es von Hand geschrieben wurde und auf einem anderen Beispiel basiert.

+0

Das Problem bei dieser Methode ist, dass ich nicht ein Ereignis sehe ich anbringen könnte an, die mich benachrichtigen würde, wenn sich das Ansichtsfenster so geändert hat, dass die Schaltflächen sichtbar gemacht werden müssen. Also müsste ich die Buttons immer sichtbar machen, was ich nicht mag. – Nick

1

Hier ist eine weitere Option. Überschreiben Sie die Standardvorlage für SCrollviewer und behandeln Sie die Schaltflächen als PageUp/PageDown. Mein Beispiel unten ist ein Scrollviewer, der vertikal scrollt. Sie können problemlos zu horizontalem Scrollen wechseln und die Handler von PageUp/PageDown zu Left und Right Handlern ändern.

<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 wird lahm. Meine Änderungen werden nicht angezeigt. Offensichtlich fehlen dem obigen Beispiel einige Informationen oben in der Steuerungsvorlage, aber in der Bearbeitungsansicht ist alles vorhanden. Es ist möglich, die ScrollViewer-Vorlage einfach zu überschreiben, um den Button-Only-Effekt zu erhalten. – Louis

+0

Post es zu Pastebin? –

+0

Dies scheint eine WPF-Lösung zu sein. Wie geht es in Silverlight? Das Command = "ScrollBar.PageUpCommand" funktioniert nicht in Silverlight. –

0

ich für Arbeitslösung für ziemlich viel gesucht haben der Zeit jetzt. Und basierend auf Louis 'Lösung habe ich es geschafft, es zum Laufen zu bringen. (in WPF)

Diese Lösung ist für horizontale Scrollen.

Zum einen fügen 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> 

Und eine modifizierte Vorlage von Louis Antwort für horizontales Scrollen:

<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>