WPF ListBox você pode fazê-lo ciclo? IE não bater paradas duras na parte superior e inferior
-
23-08-2019 - |
Pergunta
Eu tenho um WPF ListBox vinculado a um objeto de dados. Dentro da caixa de listagem são uma série de imagens com texto. Ele é colocado para fora de uma forma horizontal, e passar o mouse sobre os lados esquerdo ou direito da caixa de rolagem dos itens para a esquerda ou direita, respectivamente.
digamos que há 20 itens na caixa de listagem. Eu estou tentando descobrir como quando eu bati posição 19 item (0 com base) que eu possa ciclo da caixa e começar a coleção mais, de modo que ele vai 1 -19 e assim por diante. Seria preciso também ciclo para o outro lado, de modo que se você estivesse no ponto 0, e rolado para a esquerda, você obteria 19.
Eu tentei o KeyboardNavigation.DirectionalNavigation = "Cycle", mas isso não' parece fazer nada para mim, e eu estava agarrando em palhas uma vez que este não tem nada a ver com o teclado, é tudo rato base.
<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>
Solução
A questão aqui não é realmente com o ListBox , mas com o ScrollViewer dentro de seu modelo de controle; portanto, para tornar o ciclo de itens que você vai precisar para mudar o ScrollViewer de alguma forma. Eu escrevi um controle que deriva de ScrollViewer que os ciclos em uma direção vertical ... mas deve ser fácil ver como fazê-lo funcionar na horizontal também.
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();
}
}
}
O ScrollTo ... e Linha ... métodos já existem no ScrollViewer fazer o bem simples codificação. Tudo o que eu estou fazendo aqui é verificar o deslocamento contra os limites do espectador atual antes de rolagem.
O próximo passo é o de inserir a nova
<ControlTemplate x:Key="{x:Type ListBox}" TargetType="ListBox">
...
<l:CyclicScrollViewer
Padding="{TemplateBinding Control.Padding}"
Focusable="False">
<ItemsPresenter ... />
</l:CyclicScrollViewer>
...
</ControlTemplate>
Eu publiquei um aplicativo de exemplo que usa este código aqui . Este exemplo não tem suporte ao teclado, mas que pode ser simplesmente adicionado, substituindo o OnKeyDown e executar o apropriado Linha ... comandos. Espero que isso ajude.
Outras dicas
Há uma série de implementações WPF carrossel gratuitos e comerciais que fazem isso. Dê uma olhada neste roundup http://mdavey.wordpress.com/2007 / 04/03 / WPF-carrossel /