2008-12-17 17 views
5

Estoy usando ScrollViewer como parte de mi aplicación Silverlight. Tiene una orientación horizontal, y me gustaría que aparezca de tal manera que solo aparezcan los botones de desplazamiento, pero no la barra de desplazamiento en sí. Algo parecido a esta representación ASCII crudo:Silverlight Scrollviewer con solo botones

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

Sé que podría utilizar la funcionalidad de plantillas, pero todas las muestras que he visto sólo cambian el aspecto de todos los elementos, y no su posicionamiento en bruto, o si incluso Aparecer. ¿Es posible hacer esto y podría alguien proporcionar un esquema de cómo se vería la plantilla?

Respuesta

1

He hecho algo similar y la mejor manera que encontré para hacer esto fue poner su contenido en un visor de desplazamiento y simplemente desactivar las barras de desplazamiento. Luego, codifique sus botones para desplazar el scrollviewer.

Editar: Respondiendo a comentario sobre no hay manera de lidiar con el tamaño.

En primer lugar, construirías este control como ContentControl. Debería tener una plantilla definida en generic.xaml que tenga los controles de tu botón más el visor de desplazamiento. Algo así como:

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

Luego, en el control de lo que se necesita para anular 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; 
} 

En su botón de clic manipuladores que tendría que (1) desplazarse el espectador y (2) comprobar la nueva valor de HorizontalOffset para ver si necesita ocultar o mostrar cualquiera de los botones.

Descargo de responsabilidad: Probablemente este código no funcione como está, ya que fue escrito a mano y basado en un ejemplo diferente.

+0

El problema con este método es que no veo un evento que podría adjuntar a, que me notificará cuando la ventana gráfica haya cambiado de tal manera que los botones deben hacerse visibles. Entonces, en efecto, tendré que hacer que los botones estén siempre visibles, lo que no me gusta. – Nick

1

Aquí hay otra opción. Reemplace la plantilla predeterminada para SCrollviewer y maneje los botones como AvPág/AvPág. Mi ejemplo a continuación es un scrollviewer que se desplaza verticalmente. Puede cambiar fácilmente a desplazamiento horizontal y cambiar los controladores desde AvPág/AvPág a manejadores izquierdo y derecho.

<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á siendo cojo. Mis ediciones no se muestran. Obviamente, al ejemplo anterior le falta algo de información en la parte superior de la Plantilla de Control, pero en la vista de edición está todo allí. Es posible anular la plantilla ScrollViewer para obtener el efecto de solo botón. – Louis

+0

¿Publicarlo en pastebin? –

+0

Esto parece ser una solución de WPF. ¿Cómo hacer en Silverlight? El comando = "ScrollBar.PageUpCommand" no funciona en Silverlight. –

0

he estado buscando la solución de trabajo para mucho de tiempo ahora. Y basado en la solución de Louis, he logrado hacerlo funcionar. (en WPF)

Esta solución es para desplazamiento horizontal.

En primer lugar, añadir 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> 

Y una plantilla modificada a partir de la respuesta de Louis por el desplazamiento horizontal:

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