WPF ListBox Можете ли вы сделать это цикл? IE не бьет жесткими стопами сверху и снизу
У меня есть WPF ListBox, связанный с объектом данных. Внутри списка находятся серии изображений с текстом. Он расположен в горизонтальном положении, а над левой или правой сторонами поля прокручиваются элементы влево или вправо соответственно.
скажем, в списке 20 пунктов. Я пытаюсь выяснить, как, когда я нажимаю на элемент позиции 19 (на основе 0), я могу циклически поменять прямоугольник и начать сбор заново, чтобы он шел 1 -19 и так далее. Также нужно будет выполнить цикл в другом направлении, чтобы, если бы вы находились на позиции 0 и прокручивали влево, вы получили бы 19.
Я пробовал KeyboardNavigation.DirectionalNavigation="Cycle", но это, похоже, ничего не делает для меня, и я цеплялся за соломинку, поскольку это не имеет ничего общего с клавиатурой, все основано на мышах.
<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>
2 ответа
Проблема здесь на самом деле не в ListBox, а в ScrollViewer внутри его шаблона управления; поэтому, чтобы сделать цикл элементов, вам нужно каким- то образом изменить ScrollViewer. Я написал элемент управления, производный от ScrollViewer, который циклически перемещается в вертикальном направлении... но должно быть легко увидеть, как заставить его работать также горизонтально.
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();
}
}
}
Методы ScrollTo... и Line... уже существуют в ScrollViewer, что делает кодирование довольно простым. Все, что я делаю здесь, это проверяет текущее смещение относительно границ зрителя перед прокруткой.
Следующим шагом является вставка нового ScrollViewer в шаблон элемента управления для целевого элемента управления, в данном случае ListBox. Вот фрагмент кода XAML, чтобы продемонстрировать это.
<ControlTemplate x:Key="{x:Type ListBox}" TargetType="ListBox">
...
<l:CyclicScrollViewer
Padding="{TemplateBinding Control.Padding}"
Focusable="False">
<ItemsPresenter ... />
</l:CyclicScrollViewer>
...
</ControlTemplate>
Я разместил пример приложения, которое использует этот код здесь. Этот образец не имеет поддержки клавиатуры, но его можно просто добавить, переопределив метод OnKeyDown и выполнив соответствующие команды Line.... Надеюсь, это поможет.
Существует ряд бесплатных и коммерческих реализаций карусели WPF, которые делают это. Посмотрите на этот обзор http://mdavey.wordpress.com/2007/04/03/wpf-carousel/