WPF ListBox ¿Puedes hacerlo circular?IE no toca paradas bruscas en la parte superior e inferior

StackOverflow https://stackoverflow.com/questions/389341

Pregunta

Tengo un ListBox de WPF vinculado a un objeto de datos.Dentro del cuadro de lista hay una serie de imágenes con texto.Está dispuesto de forma horizontal y, al pasar el mouse sobre los lados izquierdo o derecho del cuadro, se desplazan los elementos hacia la izquierda o hacia la derecha, respectivamente.

digamos que hay 20 elementos en el cuadro de lista.Estoy tratando de descubrir cómo, cuando llego al elemento de la posición 19 (basado en 0), puedo hacer un ciclo en el cuadro y comenzar la colección de nuevo, de modo que vaya del 1 al 19 y así sucesivamente.También sería necesario realizar un ciclo en sentido contrario, de modo que si estuviera en el elemento 0 y se desplazara hacia la izquierda, obtendría 19.

Probé KeyboardNavigation.DirectionalNavigation="Cycle" pero no parece hacer nada por mí, y estaba agarrando un clavo ardiendo ya que esto no tiene nada que ver con el teclado, todo está basado en el mouse.

        <ListBox ItemsSource="{Binding Source={StaticResource WPFApparelCollection}}" Margin="24,-7,39,-19" ScrollViewer.VerticalScrollBarVisibility="Hidden" ScrollViewer.HorizontalScrollBarVisibility="Hidden" SelectionMode="Single" x:Name="list1" MouseLeave="List1_MouseLeave" MouseMove="List1_MouseMove" Style="{DynamicResource ListBoxStyle1}" Background="Transparent" BorderThickness="0">
            <ListBox.Resources>
                <!-- override the system brushes so that selected items are transparent whether the ListBox has focus or not -->
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
                <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" />
            </ListBox.Resources>
            <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Setter Property="Background" Value="Transparent" />
                    <Setter Property="HorizontalContentAlignment" Value="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
                    <Setter Property="VerticalContentAlignment" Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
                    <Setter Property="Padding" Value="20,10,20,10" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                                <Border x:Name="Bd" SnapsToDevicePixels="true" Background="Transparent" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
                                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                                </Border>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsSelected" Value="true">
                                        <Setter Property="Background" TargetName="Bd" Value="Transparent" />
                                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
                                    </Trigger>
                                    <MultiTrigger>
                                        <MultiTrigger.Conditions>
                                            <Condition Property="IsSelected" Value="true" />
                                            <Condition Property="Selector.IsSelectionActive" Value="false" />
                                        </MultiTrigger.Conditions>
                                        <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
                                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
                                    </MultiTrigger>
                                    <Trigger Property="IsEnabled" Value="false">
                                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListBox.ItemContainerStyle>
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel Orientation="Horizontal" IsItemsHost="True" />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Vertical">
                        <Image Source="{Binding Image}" MouseLeave="Image_MouseLeave" MouseEnter="Image_MouseEnter" Cursor="Hand" Tag="{Binding Link}" MouseLeftButtonDown="Image_MouseLeftButtonDown" VerticalAlignment="Top" HorizontalAlignment="Left"></Image>
                        <Label Content="{Binding Name}" Cursor="Hand" Tag="{Binding Link}" MouseLeftButtonDown="Label_MouseLeftButtonDown" VerticalAlignment="Bottom" Foreground="White" Style="{StaticResource Gotham-Medium}" FontSize="8pt" HorizontalAlignment="Center" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
¿Fue útil?

Solución

El problema aquí no es realmente con el Cuadro de lista, pero con el Visor de desplazamiento dentro de su plantilla de control;por lo tanto, para hacer que los artículos se ciclen necesitarás cambiar el Visor de desplazamiento de alguna manera.He escrito un control que se deriva de Visor de desplazamiento que circula en dirección vertical...pero debería ser fácil ver cómo hacer que funcione horizontalmente también.

public class CyclicScrollViewer : ScrollViewer
{
    public CyclicScrollViewer()
    {
        this.CommandBindings.Add(new CommandBinding(ScrollBar.LineUpCommand, LineCommandExecuted));
        this.CommandBindings.Add(new CommandBinding(ScrollBar.LineDownCommand, LineCommandExecuted));
    }

    private void LineCommandExecuted(object sender, ExecutedRoutedEventArgs e)
    {
        if (e.Command == ScrollBar.LineUpCommand)
        {
            if (this.VerticalOffset == 0)
                this.ScrollToEnd();
            else
                this.LineUp();
        }

        if (e.Command == ScrollBar.LineDownCommand)
        {
            if (this.VerticalOffset == this.ScrollableHeight)
                this.ScrollToTop();
            else
                this.LineDown();
        }
    }
}

El Desplazarse a... y Línea... ya existen métodos en el Visor de desplazamiento haciendo que la codificación sea bastante simple.Todo lo que estoy haciendo aquí es verificar el desplazamiento actual con respecto a los límites del visor antes de desplazarme.

El siguiente paso es insertar el nuevo Visor de desplazamiento en la plantilla de control para el control de destino, en este caso el Cuadro de lista.Aquí hay un fragmento de XAML para demostrar esto.

        <ControlTemplate x:Key="{x:Type ListBox}" TargetType="ListBox">
            ...
                <l:CyclicScrollViewer 
                    Padding="{TemplateBinding Control.Padding}" 
                    Focusable="False">
                    <ItemsPresenter ... />
                </l:CyclicScrollViewer>
            ...
        </ControlTemplate>

He publicado una aplicación de muestra que usa este código. aquí.Este ejemplo no tiene soporte para teclado, pero se puede agregar simplemente anulando el OnKeyDown método y ejecutando las medidas apropiadas Línea... comandos.Espero que esto ayude.

Otros consejos

Hay una serie de implementaciones libres y comerciales carrusel de WPF que hacen esto. Echar un vistazo a este http://mdavey.wordpress.com/2007 / 04/03 / WPF-carrusel /

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top